2010-05-20 70 views
2

我在寻找最有效的方式将元素添加到一个逗号分隔的字符串,同时保持单词字母顺序删除元素:有效的方式从一个逗号分隔的字符串

例如:

string = 'Apples, Bananas, Grapes, Oranges' 
subtraction = 'Bananas' 
result = 'Apples, Grapes, Oranges' 

此外,一种方法可以做到这一点,但同时保持编号:

string = '1:Apples, 4:Bananas, 6:Grapes, 23:Oranges' 
subtraction = '4:Bananas' 
result = '1:Apples, 6:Grapes, 23:Oranges' 

示例代码是极大的赞赏。非常感谢。

+1

你真的需要使用字符串作为数据结构,或者你可以有一本字典或设置在幕后,只是*打印*作为一个逗号分隔的字符串? – 2010-05-20 08:01:54

+0

不幸的是,它是一个要求:(。谢谢但 – ensnare 2010-05-20 08:08:40

+0

我看不出你提供的两种情况之间的区别,也许你的意思是你想保留*字母*顺序,尽管ID在前面,而不是在相同的顺序?但是,如果排序顺序是正确的,那么两种情况是相同的。 – UncleZeiv 2010-05-20 09:30:52

回答

1

理想的情况下,这样的:

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不返回从删除()新的列表,所以你不能这样做,所有在同一行,而需要临时变量等类似的解决方案,它的工作是:

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) 

这也让在同一时间处理多个清除的优势。由于输入格式和删除格式非常相似,并且输入格式有多个项目,因此删除格式可能也需要支持它们 - 或者至少有这种支持是有用的。

注意,这样做(重新使用搜索)这种方式将使其难以检测不过不要验证项目;它只会扫描任何事情。作为一个黑客,你可以指望在输入逗号和报告的东西可能无法解析警告:

if items_found < (num_commas + 1): 
    print warning_str 

这将警告逗号没有空格为好。

要正确解析更复杂的输入字符串,您需要将其分解为单独的标记,在解析时跟踪输入行和列,为意外事件打印错误,甚至可以处理诸如回溯和图形构建之类的内容以获取更多复杂的输入,如源代码。对于这类东西,请查看pyparsing模块(这是第三方下载;它不包含python)。

0
>>> import re 
>>> re.sub("Bananas, |, Bananas$", "", "Apples, Bananas, Grapes, Oranges") 
'Apples, Grapes, Oranges' 

import re 
strng = '1:Apples, 4:Bananas, 6:Grapes, 23:Oranges' 
subtraction = '4:Bananas' 
result = re.sub(subtraction + ", |, " + subtraction, "", strng) 
print result 

这适用于你的例子,但需要进行修改,如果减法字符串可能包含如下[].*?{}\正则表达式元字符。

正如一位评论者指出的那样,这是一个低级别的字符串操作。它可能正常工作,但考虑到数据结构的方法应该更可靠。在逗号/空格分割是否足够,或者您是否需要csv模块的健壮性取决于您期望的可能输入字符串。

+0

我没有认为这处理了第一个/最后一个项目是要被删除的情况,换句话说,它不是将输入视为数据列表(如指定的那样),而是将其视为低级别的字符串 – 2010-05-20 09:34:32

+0

它确实处理了第一个案例;我现在已经修改了它也处理了最后,但我与你,这需要更高层次的结构考虑的一个方法可能是最好同意在规范,输入*是*字符串,而不是一个名单,虽然。 – 2010-05-20 10:07:06

1

上述马修的评论是正确的做法,但如果你是确保,(逗号后面有一个空格)发生作为分隔符,那么像这样的工作

def remove(str, element): 
    items = str.split(", ") 
    items.remove(element) 
    return ", ".join(items) 

我不会”不过建议你使用字符串作为列表。他们是为不同的目的而设计的,遵循Matthew的建议是正确的。