如何根据谓词将列表划分为较小的列表?

时间:2017-08-07 04:13:30

标签: python list

假设我有一个这样的列表:

[('Yadda', 5), ('Yadda', 9), ('Blah', 12), ('Blah', 2), ('Blah', 4)]

我想把它转换成这样的列表:

[ [('Yadda', 5), ('Yadda', 9)], [('Blah', 12), ('Blah', 2), ('Blah', 4)] ]

假设列表按照应该拆分的谓词进行排序 -

Pythonic的做法是什么?

是否有任何功能可以执行此操作或我是否必须自己编写?

5 个答案:

答案 0 :(得分:8)

您可以使用itertools.groupby

from itertools import groupby

l = [('Yadda', 5), ('Yadda', 9), ('Blah', 12), ('Blah', 2), ('Blah', 4)]

l.sort(key=lambda item: item[0])

result = [list(group) for _, group in groupby(l, key=lambda item: item[0])]

答案 1 :(得分:1)

itertools的Groupby将相邻元素分组。

>>> from itertools import groupby
>>> l = [('Yadda', 5), ('Yadda', 9), ('Blah', 12), ('Blah', 2), ('Blah', 4)]
>>> print [list(group) for _, group in groupby(l, key=lambda item: item[0])]
[[('Yadda', 5), ('Yadda', 9)], [('Blah', 12), ('Blah', 2), ('Blah', 4)]]
>>>
>>> #if the list is not sorted!     
>>> l2 = [('Yadda', 9), ('Blah', 12), ('Blah', 2), ('Blah', 4), ('Yadda', 5)]
>>> print [list(group) for _, group in groupby(l2, key=lambda item: item[0])]
[[('Yadda', 9)], [('Blah', 12), ('Blah', 2), ('Blah', 4)], [('Yadda', 5)]]
  • 在继续之前对列表进行排序非常重要!

排序后,

>>> l2 = [('Yadda', 9), ('Blah', 12), ('Blah', 2), ('Blah', 4), ('Yadda', 5)]
>>> get_first=key=lambda item: item[0]
>>> print [list(group) for _, group in groupby(sorted(l2,key=get_first), get_first)]
[[('Blah', 12), ('Blah', 2), ('Blah', 4)], [('Yadda', 5), ('Yadda', 9)]]
  • 您也可以使用过滤器!

如,

>>> l=[('Yadda', 5), ('Yadda', 9), ('Blah', 12), ('Blah', 2), ('Blah', 4)]
>>> s=set(map(lambda item: item[0],l))
>>> print [filter(lambda x:name in x,l) for name in s]
[[('Blah', 12), ('Blah', 2), ('Blah', 4)], [('Yadda', 5), ('Yadda', 9)]]
  • 您也可以使用itemgetter,

即,

>>> l=[('Yadda', 5), ('Yadda', 9), ('Blah', 12), ('Blah', 2), ('Blah', 4)]
>>> from operator import itemgetter
>>> s=set(map(itemgetter(0),l))
>>> print [filter(lambda x:name in x,l) for name in s]
[[('Blah', 12), ('Blah', 2), ('Blah', 4)], [('Yadda', 5), ('Yadda', 9)]]

答案 2 :(得分:0)

假设您根据内部列表的第一项拆分列表,我会使用字典。

l = [('Yadda', 5), ('Yadda', 9), ('Blah', 12), ('Blah', 2), ('Blah', 4)]
d={}
for x in l:
  if x[0] not in d:
    d[x[0]]=[x]
  else:
    d[x[0]].append(x)
print(d.values())

答案 3 :(得分:0)

我已经用这种方式解决了。

list = [('Yadda', 9), ('Blah', 12), ('Blah', 2), ('Blah', 4), ('Yadda', 5)]
ls_set = (set([ls[0] for ls in list]))
ls_dict = {}
for ls in ls_set:
    ls_dict[ls] = []
for ls in list:
    ls_dict[ls[0]].append(ls[1])
final_list = []
for key, value in ls_dict.items():
    a = []
    for i in value:
        a.append(tuple([key,i]))
    final_list.append(a)
print(final_list)

答案 4 :(得分:0)

如果你想要没有任何包或itertools,那么这将对你有帮助,

>>> l = [('Yadda', 5), ('Yadda', 9), ('Blah', 12), ('Blah', 2), ('Blah', 4)]
>>> l.sort(key= lambda x:x[1])
>>> values = set(map(lambda x:x[0], l))
>>> [[y for y in l if y[0]==i] for i in values]
[[('Blah', 2), ('Blah', 4), ('Blah', 12)], [('Yadda', 5), ('Yadda', 9)]]
>>> 
相关问题