2013-08-14 2 views
2

Я ищу способ сделать это в Python без большого кода котельной плиты.Работа фильтра в Python

Предположим, у меня есть список:

[(a,4),(b,4),(a,5),(b,3)] 

Я пытаюсь найти функцию, которая позволит мне сортировать по первому значению кортежа, и объединить список значений вместе, как так:

[(a,[4,3]),(b,[4,5])] 

Я знаю, что могу сделать это наивным способом, но мне было интересно, есть ли лучший способ.

+3

Как 5 превратили в 3 на вашем выходе? – roippi

ответ

2

Использование collections.defaultdict(list):

from collections import defaultdict 

lst = [("a",4), ("b",4), ("a",5), ("b",3)] 

result = defaultdict(list) 
for a, b in lst: 
    result[a].append(b) 

print sorted(result.items()) 

# prints: [('a', [4, 5]), ('b', [4, 3])] 

До своего рода алгоритм имеет сложность O(n); группа по алгоритму имеет O(n * log(n)) и набор/список/ДИКТ понимание есть нечто большее, чем O(n^2)

+0

'i [0]' и 'i [1]'? Почему бы просто не распаковать кортеж? – user2357112

+0

Нет, это не так. 'для ключа, значение в lst:' – user2357112

+0

ах, настоящая причина в том, что это 1:22 –

0

Если предположить, что «а» ваш первоначальный список «Ъ» является ожидаемый результат, следующий код будет работать:

d = {} 
for k, v in a: 
    if k in d: 
     d[k].append(v) 
    else: 
     d[k] = [v] 
b = d.items() 
+0

Это наивное решение, которое я написал –

+0

Это еще один вариант: [(ключ, [v2 для k2, v2 в a if k2 == key]) для ключа в списке (set (map (lambda x: x [0], a)))] –

0

Не так эффективно, но достаточно (с набором + список + Dict постижение):

>>> data = [("a",4), ("b",4), ("a",5), ("b",3)] 
>>> {key: [v for k, v in data if k == key] 
... for key in {k for k, v in data} 
... }.items() 
[('a', [4, 5]), ('b', [4, 3])] 
+0

Я уверен, что это хорошо, но кошмар для чтения, я хочу, чтобы люди на любом уровне питона читали его. –

+0

Это нигде не хорошо, но это способ сделать это без использования каких-либо утверждений: D –

+0

Это действительно неэффективно, но я все же считаю, что это проще всего понять. –

0

Другой вариант (опять-таки при условии, 'а' первоначальный список)

[(key,[v2 for k2, v2 in a if k2 == key ]) for key in list(set(map(lambda x: x[0], a)))] 
+0

Листинг в 'list' не требуется, так как набор уже является итерируемым. –

Смежные вопросы