2013-05-02 3 views
1

У меня есть вложенный список спаренных данных в формате:Python: Вложенный список Модификация

mylist = [['item1', 'some other stuff', 'value1'],['item1', 'some other stuff', 'value2'],['item2', 'some other stuff', 'value3'],['item2', 'some other stuff', 'value4']] 

Я понятия не имею, как это сделать следующее, но мне нужно:

Мне нужен список должны быть сгруппированы так:

[['item1', 'value1', 'value2'], ['item2', 'value3', 'value4']] 

так что для моего списка пунктов, все значения должны быть сгруппированы с их соответствующим элементом, если элемент повторяется несколько раз в списке с различными значениями.

Любая помощь была бы принята с благодарностью.

Благодаря

ответ

4

Давайте начнем с использования словаря, чтобы сопоставить элементы со списком значений. Это будет намного проще (и быстрее), чем список, потому что выяснить, какой список добавить новое значение, это просто mydict[item] вместо того, чтобы писать какую-то функцию линейного поиска.

mydict = {} 
for item, otherstuff, value in mylist: 
    mydict.setdefault(item, []).append(value) 

Это дает:

{'item1': ['value1', 'value2'], 'item2': ['value3', 'value4']} 

Теперь мы можем преобразовать этот словарь обратно в список, если вы хотите:

groupedlist = [[k] + v for k, v in mydict.items()] 

Это дает:

[['item2', 'value3', 'value4'], ['item1', 'value1', 'value2']] 

Большой недостаток здесь заключается в том, что как только вы вставляете вещи в диктофон, вы теряете любой первоначальный порядок. Если вы ожидали, что item1 будет первым, потому что его первая запись была сделана до первой записи item2 (или потому, что последняя запись item2 появилась после item1, может быть?), Вы потеряли это. Если это важно, вы можете использовать OrderedDict.

Большой потенциал - это то, что часто вам нужен словарь в конце, а не список.

Меньший потенциал роста заключается в том, что если ваши данные не отсортированы, groupby(…sorted(…)) требует сортировку O (NlogN), тогда как это решение равно O (N). Обычно это не изменит ситуацию. И если это произойдет, различия в постоянном коэффициенте для данной реализации и платформы Python могут перевесить различия в любом случае. Но если производительность важна, проверьте оба решения и используйте более быстрый.

+0

Большое спасибо, это было невероятно полезно. – user2236076

2

Вы могли бы использовать itertools.groupby, если список не отсортирован согласно первому пункту, то вы, возможно, придется сортировать его первым. Это приведет к сложности сложности для несортированных данных и O(N) для отсортированных данных.

>>> from itertools import groupby 
>>> [[k]+[x[-1] for x in v] for k,v in groupby(mylist,key=lambda x:x[0])] 
[['item1', 'value1', 'value2'], ['item2', 'value3', 'value4']] 

Использование defaultdict, он будет работать как для отсортированных и неупорядоченных данных в O(N) сложности.

>>> from collections import defaultdict 
>>> dic=defaultdict(list) 
>>> for x in mylist: 
...  key=x[0] 
...  dic[key].append(x[-1]) 
...  
>>> [[k]+v for k,v in dic.items()] 
[['item2', 'value3', 'value4'], ['item1', 'value1', 'value2']] 
+1

Не совсем. Вам нужны 'x [2]' или 'x [-1]' здесь, а не 'x [1]'. – abarnert

+0

@abarnert ой! OP изменил вход. –

+0

Для будущих читателей: Если бы я был ОП, я, вероятно, принял бы этот ответ вместо моего. Если вы действительно хотите закончить диктофон, построение dict делает ваше намерение очевидным, но если вы хотите получить «список [где] значения должны быть сгруппированы ...», я думаю, что «groupby» говорит об этом более четко. – abarnert

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