Как преобразовать список 2-списков с ключами в список N-списков с одинаковыми ключами?

1

Как создать список списков с первым элементом как ключом:

От:

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'] ]
  • 1
    Всегда ли вход сортируется по первому элементу списка?
Теги:

5 ответов

5
Лучший ответ

Поскольку вы хотите группировать свои значения в отношении ключа, это, вероятно, не 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']]
  • 0
    Но ОП хочет список списков, а не список списков?
  • 0
    @DYZ Я полагаю, что выбор списков лучше для того, что хочет ОП.
Показать ещё 4 комментария
0

Я предлагаю вам это решение, которое не оптимизировано, но легко читается:

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']]
0

Используйте 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']]
  • 0
    Вы должны отсортировать список по будущему ключу группировки перед использованием groupby . К счастью, список в оригинальном сообщении отсортирован, но если это не так, groupby даст неправильный ответ.
  • 2
    Во-первых, откуда ты знаешь? Вы спрашивали ОП? Во-вторых, ваше замечание грубо и не относится к SO.
Показать ещё 2 комментария
0

Это использует вложенное понимание:

[[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']]
0

Самый пифонический способ - группировать похожие элементы с помощью 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']]

Кстати, в списках нет ключей. (Но словари делают.)

  • 0
    Может ли кто-то из трех downvoters объяснить, что, по их мнению, не так с этим решением?
  • 1
    Отличный ответ! +1. SQL groupby - это первое, что пришло в голову, когда я увидел этот вопрос. Однако стоит отметить, что основанное на dict решение является O(n) <s>, тогда как это решение в O(n log(n)) из-за вызова sorted </ s>. РЕДАКТИРОВАТЬ : это на самом деле O(n) если вход сортируется, потому что TimSort работает в линейное время для отсортированного ввода.
Показать ещё 3 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню