Наиболее заметным отличием является область. Массив VLA будет действителен только внутри области, где он объявлен, тогда как динамический массив будет доступен везде в программе до тех пор, пока вы не назовете free()
.
На практике VLA может быть быстрее, чем динамическая память , если компилятор использует распределение стека для VLA. Однако он не указывается стандартом C, где выделен VLA.
(Компилятор мог теоретически распределить VLA в куче, но тогда компилятор также будет отвечать за очистку. Я не думаю, что такие решения существуют. Каждый компилятор, который я использовал всегда объявлять VLA в стеке.)
Это означает, что VLA не подходят для хранения больших объемов данных: вы рискуете переполнением стека. Однако это не проблема, когда вы используете динамическую память.
VLAs не имеют такой же переносимости, как и динамические массивы, поскольку ужасно старые компиляторы не поддерживают VLA. Теоретически, новым компиляторам C11 также не нужно поддерживать VLA, хотя на данный момент я знаю, что никакой компилятор не был настолько глуп, чтобы отказаться от этой поддержки.
Сравнение / сводка:
Используйте 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'}
cycle
хорошо, но я добавлю этот подход по модулю:
{L1[i]: L2[i % len(L2)] for i in range(len(L1))]}
Используйте 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)
Вы также можете использовать 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
.
Другой вариант без зависимостей со старым добрым циклом 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'}