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

Python 如何根据谓词将列表划分为更小的列表?,python,list,Python,List,假设我有这样一个列表: [('Yadda', 5), ('Yadda', 9), ('Blah', 12), ('Blah', 2), ('Blah', 4)] [ [('Yadda', 5), ('Yadda', 9)], [('Blah', 12), ('Blah', 2), ('Blah', 4)] ] 我想把它转换成如下列表: [('Yadda', 5), ('Yadda', 9), ('Blah', 12), ('Blah', 2), ('Blah', 4)] [ [('Yadd

假设我有这样一个列表:

[('Yadda', 5), ('Yadda', 9), ('Blah', 12), ('Blah', 2), ('Blah', 4)]
[ [('Yadda', 5), ('Yadda', 9)], [('Blah', 12), ('Blah', 2), ('Blah', 4)] ]
我想把它转换成如下列表:

[('Yadda', 5), ('Yadda', 9), ('Blah', 12), ('Blah', 2), ('Blah', 4)]
[ [('Yadda', 5), ('Yadda', 9)], [('Blah', 12), ('Blah', 2), ('Blah', 4)] ]
假设列表按其应拆分的谓词排序-

什么是蟒蛇式的方法


是否有任何函数可以执行此操作,或者我必须自己编写此操作?

您可以使用
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])]

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

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())

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)]]
  • 你也可以使用过滤器
作为

  • 您还可以使用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)]]

我就是这样解决的

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)

如果您不需要任何软件包或
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)]]
>>> 

结帐类似的问题值得一提的是,只有当您想要将列表作为一个列表时,列表理解才是必要的
groupby本身会返回一个迭代器,所以如果您所做的只是迭代,那就足够了。或者
key=operator.itemgetter(0)
@StevenRumbalski是的,
operator.itemgetter
可以。我认为使用lambda函数更容易理解,关键是一个单参数函数。groupby group只包含相邻元素!这会导致错误的输入输出,如测试您给出的列表后的
[('Yadda',9),('Blah',12),('Blah',2),('Blah',4),('Yadda',5)]
@keerthanarabahakaran Yes。我们应该在分组之前进行排序。