Как создать список списков с первым элементом как ключом:
От:
myList = [ [26, 'hello'], [26, 'hola'], [26, 'hi'], [26, 'bonjour'], [27, 'bye'],[27, 'doei'], [27, 'see you'], [27, 'tot ziens'] ]
Для того, чтобы:
[ [26, 'hello', 'hola', 'hi', 'bonjour'], [27, 'bye', 'doei', 'see you', 'tot ziens'] ]
Поскольку вы хотите группировать свои значения в отношении ключа, это, вероятно, не list
вы ищете как вывод, а dict
. Впоследствии это позволит постоянно искать время.
myList = [[26, 'hello'], [26, 'hola'], [26, 'hi'], [26, 'bonjour'],
[27, 'bye'], [27, 'doei'], [27, 'see you'], [27, 'tot ziens']]
myDict = {}
for k, v in myList:
myDict.setdefault(k, []).append(v)
print(myDict)
{26: ['hello', 'hola', 'hi', 'bonjour'], 27: ['bye', 'doei', 'see you', 'tot ziens']}
Хотя, если вам абсолютно необходим список списков, вы можете получить его так:
# Only valid in Python3, use [k] + v in Python2
listOfLists = [[k, *v] for k, v in myDict.items()]
print(listOfLists)
[[26, 'hello', 'hola', 'hi', 'bonjour'], [27, 'bye', 'doei', 'see you', 'tot ziens']]
Я предлагаю вам это решение, которое не оптимизировано, но легко читается:
from collections import defaultdict
myList = [ [26, 'hello'], [26, 'hola'], [26, 'hi'], [26, 'bonjour'], [27, 'bye'],[27, 'doei'], [27, 'see you'], [27, 'tot ziens'] ]
d = defaultdict(list)
for [k,v] in myList:
d[k].append(v)
newList = [[k,*v] for k,v in d.items()]
print(newList) # [[26, 'hello', 'hola', 'hi', 'bonjour'], [27, 'bye', 'doei', 'see you', 'tot ziens']]
Используйте itertools.groupby
и понимание списка
>>> from itertools import groupby
>>> from operator import itemgetter
>>> myList = [ [26, 'hello'], [26, 'hola'], [26, 'hi'], [26, 'bonjour'], [27, 'bye'],[27, 'doei'], [27, 'see you'], [27, 'tot ziens'] ]
>>> [[k] + [e[1] for e in grps] for k,grps in groupby(myList, itemgetter(0))]
[[26, 'hello', 'hola', 'hi', 'bonjour'], [27, 'bye', 'doei', 'see you', 'tot ziens']]
groupby
. К счастью, список в оригинальном сообщении отсортирован, но если это не так, groupby
даст неправильный ответ.
Это использует вложенное понимание:
[[y, *[x[1] for x in myList if x[0]==y]] for y in set([z[0] for z in myList])]
Выход:
[[26, 'hello', 'hola', 'hi', 'bonjour'], [27, 'bye', 'doei', 'see you', 'tot ziens']]
Самый пифонический способ - группировать похожие элементы с помощью itertool.groupby
. Перед группировкой список должен быть отсортирован по тому же ключу, который будет использоваться для группировки.
from itertools import groupby
[([key] + [word for _, word in words]) for key, words
in groupby(sorted(myList), key=lambda x: x[0])]
#[[26, 'bonjour', 'hello', 'hi', 'hola'],
# [27, 'bye', 'doei', 'see you', 'tot ziens']]
Кстати, в списках нет ключей. (Но словари делают.)
dict
решение является O(n)
<s>, тогда как это решение в O(n log(n))
из-за вызова sorted
</ s>. РЕДАКТИРОВАТЬ : это на самом деле O(n)
если вход сортируется, потому что TimSort работает в линейное время для отсортированного ввода.