评估两个或多个列表

时间:2009-09-28 11:24:59

标签: python list

你好,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]

但要分为多个列表?

如果您有多种类型的数据怎么办?

9 个答案:

答案 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)