Создайте словарь, сжав два списка разной длины
У меня есть два списка разной длины, L1 и L2. L1 длиннее L2. Я хотел бы получить словарь с членами L1 в качестве ключей и членами L2 в качестве значений.
Как только все члены L2 израсходованы. Я хотел бы начать все сначала и начать снова с L2 [0].
L1 = ['A', 'B', 'C', 'D', 'E']
L2 = ['1', '2', '3']
D = dict(zip(L1, L2))
print(D)
Как и ожидалось, на выходе это:
{'A': '1', 'B': '2', 'C': '3'}
Я хотел бы добиться следующего:
{'A': '1', 'B': '2', 'C': '3', 'D': '1', 'E': '2'}
Ответы
Ответ 1
Используйте itertools.cycle
чтобы перейти к началу L2
:
from itertools import cycle
dict(zip(L1, cycle(L2)))
# {'A': '1', 'B': '2', 'C': '3', 'D': '1', 'E': '2'}
В вашем случае объединение L2
с самим собой также работает.
# dict(zip(L1, L2 * 2))
dict(zip(L1, L2 + L2))
# {'A': '1', 'B': '2', 'C': '3', 'D': '1', 'E': '2'}
Ответ 2
Используйте itertools.cycle:
from itertools import cycle
L1 = ['A', 'B', 'C', 'D', 'E']
L2 = ['1', '2', '3']
result = dict(zip(L1, cycle(L2)))
print(result)
Выход
{'E': '2', 'B': '2', 'A': '1', 'D': '1', 'C': '3'}
В качестве альтернативы вы можете использовать перечисление и индекс L2
по модулю длины L2
:
result = {v: L2[i % len(L2)] for i, v in enumerate(L1)}
print(result)
Ответ 3
cycle
в порядке, но я добавлю этот подход по модулю:
{L1[i]: L2[i % len(L2)] for i in range(len(L1))]}
Ответ 4
Вы также можете использовать collections.deque()
для создания циклической очереди FIFO:
from collections import deque
L1 = ['A', 'B', 'C', 'D', 'E']
L2 = deque(['1', '2', '3'])
result = {}
for letter in L1:
number = L2.popleft()
result[letter] = number
L2.append(number)
print(result)
# {'A': '1', 'B': '2', 'C': '3', 'D': '1', 'E': '2'}
Который выталкивает самый левый элемент, который в настоящее время находится в L2
и добавляет его в конец, как только число добавляется в словарь.
Примечание. Обе collections.deque.popleft()
и collections.deque.append()
являются операциями O (1), так что выше все равно O (N), так как вам нужно пройти все элементы в L1
.
Ответ 5
Другой вариант без зависимостей с хорошим старым for
цикла:
D = {}
for i, e in enumerate(L1):
D[e] = L2[i%len(L2)]
D #=> {'A': '1', 'B': '2', 'C': '3', 'D': '1', 'E': '2'}
Или просто:
{ e: L2[i%len(L2)] for i, e in enumerate(L1) }
#=> {'A': '1', 'B': '2', 'C': '3', 'D': '1', 'E': '2'}