2009-12-06 3 views
3

Я хочу преобразовать список кортежей во вложенный список, используя Python. Как мне это сделать?Преобразование списка кортежей во вложенный список с использованием Python

У меня есть упорядоченный список кортежей (отсортированный по второму значению):

[(1, 5), (5, 4), (13, 3), (4, 3), (3, 2), (14, 1), (12, 1), 
(10, 1), (9, 1), (8, 1), (7, 1), (6, 1), (2, 1)] 

Теперь я хочу его иметь, как это (второе значение игнорируется и вложен в списках):

[ [1], [5], [13, 4], [3], [14, 12, 10, 9, 8, 7, 6, 2] ] 

Я видел другие темы здесь с map, используемыми для таких вещей, но я не совсем понимаю это. Может ли кто-нибудь дать представление о «правильном» способе python для этого?

ответ

11
from operator import itemgetter 
from itertools import groupby 

lst = [(1, 5), (5, 4), (13, 3), (4, 3), (3, 2), (14, 1), 
     (12, 1), (10, 1), (9, 1), (8, 1), (7, 1), (6, 1), (2, 1)] 

result = [[x for x, y in group] 
      for key, group in groupby(lst, key=itemgetter(1))] 

groupby(lst, key=itemgetter(1)) формирует группы последовательных элементов lst в которой все элементы имеют тот же 1-й (с нуля). [x for x, y in group] сохраняет 0-й элемент каждого элемента в каждой группе.

+0

Мне это понравилось. простой и без отображения. – proxylittle

+0

oh игнорировать его. nvm .. опечатка. – proxylittle

+0

Вероятно, 'sort' - это список целых чисел, а не список 2-х кортежей. –

0

Не знаю, как быстро это будет для больших наборов, но вы могли бы сделать что-то вроде этого:

input = [ 
    (1, 5), (5, 4), (13, 3), (4, 3), (3, 2), (14, 1), 
    (12, 1), (10, 1), (9, 1), (8, 1), (7, 1), (6, 1), 
    (2, 1) 
] 

output = [[] for _ in xrange(input[0][1])] 
for value, key in input: 
    output[-key].append(value) 

print output # => [[1], [5], [13, 4], [3], [14, 12, 10, 9, 8, 7, 6, 2]] 
+0

Вы считаете, что len (output) должен соответствовать наивысшему значению ключа и что значения ключей всегда последовательны. – ironfroggy

+0

Да, я предположил, что OP хочет индексы в 'input' и' output' для соответствия - так что если вы возьмете, например, '(3, 2)' из 'input', тогда' output [-2] 'будет пустым списком. Трудно сказать только с одним набором данных. –

2

Это немного запутанным, но вы можете сделать это с помощью функции itertools.groupby:

>>> lst = [(1, 5), (5, 4), (13, 3), (4, 3), (3, 2), (14, 1), (12, 1), 
(10, 1), (9, 1), (8, 1), (7, 1), (6, 1), (2, 1)] 
>>> from operator import itemgetter 
>>> import itertools 
>>> [map(itemgetter(0), group) for (key,group) in itertools.groupby(lst, itemgetter(1))] 
[[1], [5], [13, 4], [3], [14, 12, 10, 9, 8, 7, 6, 2]] 
>>> 

Объяснение: GroupBy возвращает итератор для каждой группы, где группа определяется как последовательность записей которые имеют одинаковое значение, возвращаемое функцией, переданной как отдельный параметр. itemgetter (1) генерирует функцию, которая возвращает x [1] при вызове с аргументом x. Поскольку групповой итератор возвращает два значения - ключ, который был использован, и последовательности исходных значений, которые являются кортежами, тогда нам нужно вырезать второе значение в каждом кортеже, что и делает карта (itemgetter (0), group) ,

+0

хорошо, но ваша последняя строка сбивает с толку, потому что мне нужно научиться картографическому материалу. И я думаю, что его почти такое же роберто отправлено. Но спасибо! – proxylittle

1

Может быть, не самый pythonesque ответа, но это работает:

d = {} 

a = [(1,5), (5,4), (13,3), (4,3), (3,2), (14,1), (12,1)] 

for value in a: 
    if value[0] not in d: 
     d[ value[0] ] = [] 
    d[ value[0] ].append(a[1]) 

print d.values() 
+0

Я бы улучшил это с помощью setdefault() вместо проверки на 'значение [0] не в d' – ironfroggy

1

Простое решение:

n_list = [] 
c_snd = None 
for (fst, snd) in o_list: 
    if snd == c_snd: n_list[-1].append(fst) 
    else: 
    c_snd = snd 
    n_list.append([fst]) 

Объяснения: использовать c_snd для сохранения текущей второй части кортежа. Если это изменится, запустите новый список в n_list для этого нового второго значения, начиная с fst, иначе добавьте fst в последний список в n_list.

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