python:根据元素值生成子列表

时间:2014-04-15 13:00:36

标签: python sublist

我有一个元素列表,我想从该列表中生成任意数量的子列表。给定子列表的所有元素必须具有函数f的相同输出。

例如:

>>> mylist = [1,2,3,4,5,6] # my list to split into sublist
>>> sublists = list() # my sublists
>>> def f(e) : # the function used to discriminate the elements
...  return e%2
... 
>>> for ret in [0,1] :
...   sublists.append([e for e in mylist if f(e) == ret])
... 
>>> print(sublists)
[[2, 4, 6], [1, 3, 5]]

这很有用,但这只是因为我确切知道f可以返回哪些值:01。所以我可以迭代这些输出值,然后创建子列表。

但如果我事先不知道freturn的价值怎么办?有一个很好的Pythonic方法吗?我想避免迭代mylist只是为了看看f可以输出所有元素。

2 个答案:

答案 0 :(得分:3)

您可以使用collections.defaultdict

from collections import defaultdict

out = defaultdict(list)
for e in mylist:
    out[f(e)].append(e)

现在,只要f(e)可以使用e的所有适当值,您就会获得类似

的输出
defaultdict(<class 'list'>, {0: [2, 4, 6], 1: [1, 3, 5]})

如果您需要这些子列表的列表,则可以执行以下操作:

sublists = list(out.values())

但是请注意,字典不能保证保持合理的顺序;每个子列表将保持订购状态,但您可以

[[2, 4, 6], [1, 3, 5]]

[[1, 3, 5], [2, 4, 6]]

在这个例子中。


长形式等效于显示defaultdict的作用:

out = {}
for e in mylist:
    key = f(e)
    if key not in out:
        out[key] = []
    out[key].append(e)

答案 1 :(得分:2)

只是为了多元化:

from itertools import groupby
from operator import itemgetter

mylist = [1, 2, 3, 4, 5, 6] 
f = lambda x: x % 2

zipt = sorted((f(x), x) for x in mylist)

for x, y in groupby(zipt, key=itemgetter(0)):
    print(x, [z[1] for z in y])

打印

0 [2, 4, 6]
1 [1, 3, 5]