Group list of tuples by item

橙三吉。 提交于 2019-12-11 00:34:04

问题


I have this list as example:

[(148, Decimal('3.0')), (325, Decimal('3.0')), (148, Decimal('2.0')), (183, Decimal('1.0')), (308, Decimal('1.0')), (530, Decimal('1.0')), (594, Decimal('1.0')), (686, Decimal('1.0')), (756, Decimal('1.0')), (806, Decimal('1.0'))]

Now i want to group by the id, so I will use itemgetter(0):

import operator, itertools
from decimal import *
test=[(148, Decimal('3.0')), (325, Decimal('3.0')), (148, Decimal('2.0')), (183, Decimal('1.0')), (308, Decimal('1.0')), (530, Decimal('1.0')), (594, Decimal('1.0')), (686, Decimal('1.0')), (756, Decimal('1.0')), (806, Decimal('1.0'))]

for _k, data in itertools.groupby(test, operator.itemgetter(0)):
    print list(data) 

I don't know why but I am getting this wrong output:

[(148, Decimal('3.0'))]
[(325, Decimal('3.0'))]
[(148, Decimal('2.0'))]
[(183, Decimal('1.0'))]
[(308, Decimal('1.0'))]
[(530, Decimal('1.0'))]
[(594, Decimal('1.0'))]
[(686, Decimal('1.0'))]
[(756, Decimal('1.0'))]
[(806, Decimal('1.0'))]

As you can see the output is not grouped by id. However the code above works fine if I use itemgetter(1). The output is grouped by decimal val.

[(148, Decimal('3.0')), (325, Decimal('3.0'))]
[(148, Decimal('2.0'))]
[(183, Decimal('1.0')), (308, Decimal('1.0')), (530, Decimal('1.0')), (594, Decimal('1.0')), (686, Decimal('1.0')), (756, Decimal('1.0')), (806, Decimal('1.0'))]

What I am missing here?


回答1:


You would first need to sort the data for the groupby to work, it groups consecutive elements based on the key you provide:

import operator, itertools
from decimal import *
test=[(148, Decimal('3.0')), (325, Decimal('3.0')), (148, Decimal('2.0')), (183, Decimal('1.0')), (308, Decimal('1.0')), (530, Decimal('1.0')), (594, Decimal('1.0')), (686, Decimal('1.0')), (756, Decimal('1.0')), (806, Decimal('1.0'))]

for _k, data in itertools.groupby(sorted(test), operator.itemgetter(0)):
    print list(data)

But you would be better using a dict to group to avoid an unnecessary O(n log n) sort:

from collections import defaultdict

d = defaultdict(list)

for t in test:
    d[t[0]].append(t)

for v in d.values():
    print(v)

Both would give you the same groupings, just not necessarily in the same order.




回答2:


itertools.groupby() requires the data to be consistent or sorted.

[(148, Decimal('3.0')), (148, Decimal('2.0')), (325, Decimal('3.0'))] will work but [(148, Decimal('3.0')), (325, Decimal('3.0')), (148, Decimal('2.0'))] will not as the id is 148, 325, 148 instead of 148, 148, 325.



来源:https://stackoverflow.com/questions/39650110/group-list-of-tuples-by-item

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!