Создайте словарь, объединяя два списка разной длины [дубликаты]

Наиболее заметным отличием является область. Массив VLA будет действителен только внутри области, где он объявлен, тогда как динамический массив будет доступен везде в программе до тех пор, пока вы не назовете free().

На практике VLA может быть быстрее, чем динамическая память , если компилятор использует распределение стека для VLA. Однако он не указывается стандартом C, где выделен VLA.

(Компилятор мог теоретически распределить VLA в куче, но тогда компилятор также будет отвечать за очистку. Я не думаю, что такие решения существуют. Каждый компилятор, который я использовал всегда объявлять VLA в стеке.)

Это означает, что VLA не подходят для хранения больших объемов данных: вы рискуете переполнением стека. Однако это не проблема, когда вы используете динамическую память.

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


Сравнение / сводка:

  • VLAs следует использовать, когда имеется небольшое количество локальных данных, поскольку они имеют быстрое время распределения и автоматическую очистку.
  • Динамические массивы должны использоваться, когда есть большие объемы данных, чтобы предотвратить переполнение стека.
  • Динамические массивы должны использоваться, когда данные должны сохраняться после выполнения функции и быть доступный в другом месте программы.
  • Динамические массивы должны использоваться, когда у вас есть исключительные и / или иррациональные требования к переносимости.
29
задан cs95 8 January 2019 в 20:23
поделиться

5 ответов

Используйте 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'}
36
ответ дан cs95 8 January 2019 в 20:23
поделиться

cycle хорошо, но я добавлю этот подход по модулю:

{L1[i]: L2[i % len(L2)] for i in range(len(L1))]}
15
ответ дан schwobaseggl 8 January 2019 в 20:23
поделиться

Используйте 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)
24
ответ дан Daniel Mesejo 8 January 2019 в 20:23
поделиться

Вы также можете использовать 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.

7
ответ дан RoadRunner 8 January 2019 в 20:23
поделиться

Другой вариант без зависимостей со старым добрым циклом 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'}
5
ответ дан iGian 8 January 2019 в 20:23
поделиться
Другие вопросы по тегам:

Похожие вопросы: