2016-09-22 2 views
2

У меня есть этот список, как, например:Список групп кортежей по пункту

[(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'))] 

Теперь я хочу, чтобы группа по идентификатору, так что я буду использовать 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) 

Я не знаю, почему, но я получаю этот неправильный вывод:

Как вы можете видеть, выход не сгруппирован по идентификатору. Однако код выше работает отлично, если я использую itemgetter(1). Вывод сгруппирован по десятичному значению.

[(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'))] 

Что мне здесь недостает?

ответ

4

Сначала нужно будет сортировать данные для GroupBy работать, группирует последовательные элементы на основе ключа вы предоставляете:

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) 

Но вы бы лучше, используя Dict в группе, чтобы избежать ненужного O (N журнал п) вид:

from collections import defaultdict 

d = defaultdict(list) 

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

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

И даст вам те же группировки, просто не обязательно в т он тот же порядок.

2

itertools.groupby() требует, чтобы данные согласовывались или сортировались.

[(148, Decimal('3.0')), (148, Decimal('2.0')), (325, Decimal('3.0'))] будет работать, но [(148, Decimal('3.0')), (325, Decimal('3.0')), (148, Decimal('2.0'))] не будет, как идентификатор 148, 325, 148 вместо 148, 148, 325.