你好,codeboys和codegirls!
我遇到了一个看似简单的解决方案的简单问题。但作为一个Python新手,我觉得在某个地方有更好的方法。
假设您有一个混合字符串列表。袋中有两种基本类型的字符串 - 其中带有“=”(a =马铃薯)和没有(Lady Jane)的字符串。你需要的是将它们分成两个列表。
显而易见的方法是:
for arg in arguments:
if '=' in arg:
equal.append(arg)
else:
plain.append(arg)
还有其他更优雅的方式吗?类似的东西:
equal = [arg for arg in arguments if '=' in arg]
但要分为多个列表?
如果您有多种类型的数据怎么办?
答案 0 :(得分:4)
尝试
for arg in arguments:
lst = equal if '=' in arg else plain
lst.append(arg)
或(圣洁的丑陋)
for arg in arguments:
(equal if '=' in arg else plain).append(arg)
第三种选择:创建一个提供append()
的类,并将其分类到多个列表中。
答案 1 :(得分:4)
您可以使用itertools.groupby()
:
import itertools
f = lambda x: '=' in x
groups = itertools.groupby(sorted(data, key=f), key=f)
for k, g in groups:
print k, list(g)
答案 2 :(得分:3)
我只想进行两次列表推导。虽然这确实会产生一些开销(列表中的两个循环),但使用列表理解比使用for更为Pythonic。它(在我看来)比使用各种非常酷的技巧更具可读性,但人们对此知之甚少。
答案 3 :(得分:2)
def which_list(s):
if "=" in s:
return 1
return 0
lists = [[], []]
for arg in arguments:
lists[which_list(arg)].append(arg)
plain, equal = lists
如果您有更多类型的数据,请向which_list
添加if子句,并将lists
初始化为更多空列表。
答案 4 :(得分:2)
我会选择Edan的方法,例如
equal = [arg for arg in arguments if '=' in arg]
plain = [arg for arg in arguments if '=' not in arg]
答案 5 :(得分:2)
我在这里读到你可能对解决方案感兴趣的地方 将适用于 more 而不是两个标识符(等号和空格)。
以下解决方案只需要您更新uniques
集
你想要匹配的任何东西,结果都放在一个列表字典中
标识符作为键。
uniques = set('= ')
matches = dict((key, []) for key in uniques)
for arg in args:
key = set(arg) & uniques
try:
matches[key.pop()].append(arg)
except KeyError:
# code to handle where arg does not contain = or ' '.
现在上面的代码假设您的标识符只有一个匹配项
在arg
中。即,您没有arg
,看起来像'John= equalspace'
。
您还必须考虑如何处理与集合中的任何内容不匹配的案例(KeyError
发生。)
答案 6 :(得分:1)
另一种方法是使用filter
函数,尽管它不是最有效的解决方案
例如:
>>> l = ['a=s','aa','bb','=', 'a+b']
>>> l2 = filter(lambda s: '=' in s, l)
>>> l3 = filter(lambda s: '+' in s, l)
>>> l2
['a=s', '=']
>>> l3
['a+b']
答案 7 :(得分:1)
我把它放在一起,然后看到Ned Batchelder已经在同一个方面了。我选择打包拆分方法而不是列表选择器,并且只使用False和True的隐式0/1值。
def split_on_condition(source, condition):
ret = [],[]
for s in source:
ret[condition(s)].append(s)
return ret
src = "z=1;q=2;lady jane;y=a;lucy in the sky".split(';')
plain,equal = split_on_condition(src, lambda s:'=' in s)
答案 8 :(得分:1)
你的方法是最好的。对于仅排序到两个列表,它不能比那更清楚。如果您希望它是一个单行,请将其封装在一个函数中:
def classify(arguments):
equal, plain = [], []
for arg in arguments:
if '=' in arg:
equal.append(arg)
else:
plain.append(arg)
return equal, plain
equal, plain = classify(lst)