在Python中高效地从逗号分隔字符串中移除元素的方法
我想找一种最有效的方法,把一个元素添加到用逗号分隔的字符串中,同时保持这些词的字母顺序:
比如说:
string = 'Apples, Bananas, Grapes, Oranges'
subtraction = 'Bananas'
result = 'Apples, Grapes, Oranges'
另外,我还想知道怎么做才能保持ID不变:
string = '1:Apples, 4:Bananas, 6:Grapes, 23:Oranges'
subtraction = '4:Bananas'
result = '1:Apples, 6:Grapes, 23:Oranges'
如果能提供一些示例代码,那就太好了。非常感谢!
4 个回答
马修上面的评论是正确的做法,但如果你确定 ,
(逗号后面跟一个空格)只用作分隔符,那么像下面这样的做法是可以的。
def remove(str, element):
items = str.split(", ")
items.remove(element)
return ", ".join(items)
不过,我不建议你把字符串当作列表来用。它们是为不同的目的设计的,遵循马修的建议才是正确的做法。
理想情况下,像这样:
input_str = '1:Apples, 4:Bananas, 6:Grapes, 23:Oranges'
removal_str = '4:Bananas'
sep = ", "
print sep.join(input_str.split(sep).remove(removal_str))
应该是可以工作的。但是,Python 的 remove() 方法不会返回新的列表,所以你不能把所有操作放在一行里,需要用到临时变量等等。一个类似但可行的解决方案是:
input_str = '1:Apples, 4:Bananas, 6:Grapes, 23:Oranges'
removal_str = '4:Bananas'
sep = ", "
print sep.join([ i for i in input_str.split(sep) if i != removal_str ])
不过,为了尽可能准确,假设你不能保证所有项目都是有效的,你需要确认每个项目都符合你给出的所有要求,也就是它们的格式是数字:标识符。最简单的方法是使用 re 模块来查找特定的正则表达式格式,返回所有结果,并跳过那些不符合你要求的结果。通过使用相对简洁的代码,你可以得到一个相对简短且能很好验证的解决方案:
def str_to_dictlist(inp_str):
import re
regexp = r"(?P<id>[0-9]+):(?P<name>[a-zA-Z0-9_]+)"
return [ x.groups() for x in re.finditer(regexp, inp_str) ]
input_str = '1:Apples, 4:Bananas, 6:Grapes, 23:Oranges'
subtraction_str = "4:Bananas"
sep = ", "
input_items = str_to_dictlist(input_str)
removal_items = str_to_dictlist(subtraction_str)
final_items = [ "%s:%s" % (x,y) for x,y in input_items if (x,y) not in removal_items ]
print sep.join(final_items)
这样做还有一个好处,就是可以同时处理多个删除操作。由于输入格式和删除格式非常相似,而且输入格式包含多个项目,因此删除格式也可能需要支持这些项目,或者至少说,支持这些操作是有用的。
需要注意的是,使用这种方式(用 re 来搜索)会让你很难发现那些不符合要求的项目;它只会扫描符合要求的内容。作为一种变通方法,你可以计算输入中的逗号数量,并报告一个警告,提示可能有内容解析失败:
if items_found < (num_commas + 1):
print warning_str
这也会警告没有空格的逗号。
要正确解析更复杂的输入字符串,你需要将其分解为单独的标记,在解析时跟踪输入的行和列,打印任何意外的错误,甚至可能需要处理像回溯和图构建这样的复杂输入,比如源代码。对于这类问题,可以看看 pyparsing 模块(这是一个第三方下载,不是 Python 自带的)。