我有一个元素列表,我想从该列表中生成任意数量的子列表。给定子列表的所有元素必须具有函数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
可以返回哪些值:0
或1
。所以我可以迭代这些输出值,然后创建子列表。
但如果我事先不知道f
能return
的价值怎么办?有一个很好的Pythonic方法吗?我想避免迭代mylist
只是为了看看f
可以输出所有元素。
答案 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]