Представь, что у тебя есть:
keys = ['name', 'age', 'food']
values = ['Monty', 42, 'spam']
Какой самый простой способ создать следующий словарь?
a_dict = {'name' : 'Monty', 'age' : 42, 'food' : 'spam'}
python
list
dictionary
Guido
источник
источник
dictionary = {zip(keys, values)}
это не сработает. Вы должны явно объявить какdict(...)
{thing}
является синтаксическим сахаром для построенияset()
содержащего один элемент.{*iterable}
является синтаксическим сахаром для построения,set
содержащего несколько элементов.{k:v}
или{**mapping}
будет построитьdict
, но это синтаксический совершенно различно.{}
для словарей. На самом деле, если мы попробуем,type({})
результат будетdict
. Но действительно, если мы попробуем,type({thing})
то результат будетset
.{k:v for k, v in zip(keys, values)}
. Оказывается, мы можем. +1.Самый производительный,
dict
конструктор сzip
В Python 3 zip теперь возвращает ленивый итератор, и теперь это наиболее эффективный подход.
dict(zip(keys, values))
требуется одноразовый глобальный поиск для каждогоdict
иzip
, но он не образует ненужных промежуточных структур данных и не должен иметь дело с локальными поисками в приложении функции.Второе место, понимание слова:
Близкое второе место к использованию конструктора dict состоит в том, чтобы использовать собственный синтаксис понимания dict (не понимания списка , как ошибочно выразились другие):
Выберите это, когда вам нужно отобразить или отфильтровать на основе ключей или значения.
В Python 2
zip
возвращает список, чтобы избежать создания ненужного списка, используйтеizip
вместо этого (псевдоним zip может уменьшить изменения кода при переходе на Python 3).Итак, это все еще (2.7):
Python 2, идеально подходит для <= 2.6
izip
fromitertools
становитсяzip
в Python 3.izip
лучше, чем zip для Python 2 (потому что это избегает ненужного создания списка), и идеально подходит для 2.6 или ниже:Результат для всех случаев:
В любом случае:
Объяснение:
Если мы посмотрим на справку,
dict
то увидим, что она принимает различные формы аргументов:Оптимальным подходом является использование итерации, избегая при этом создания ненужных структур данных. В Python 2 zip создает ненужный список:
В Python 3 эквивалент будет:
и Python 3
zip
просто создает повторяемый объект:Поскольку мы хотим избежать создания ненужных структур данных, мы обычно хотим избегать Python 2
zip
(поскольку он создает ненужный список).Менее производительные альтернативы:
Это выражение генератора передается конструктору dict:
или эквивалентно:
И это понимание списка, передаваемое конструктору dict:
В первых двух случаях дополнительный слой неоперативных (таким образом, ненужных) вычислений помещается поверх итерируемого zip, а в случае понимания списка дополнительный список создается без необходимости. Я ожидал бы, что все они будут менее производительными, и конечно не более.
Обзор производительности:
В 64-битном Python 3.8.2, предоставленном Nix, в Ubuntu 16.04 упорядочен от самого быстрого до самого медленного:
dict(zip(keys, values))
выигрывает даже с небольшими наборами ключей и значений, но для больших наборов различия в производительности станут больше.Комментатор сказал:
Мы используем,
min
потому что эти алгоритмы являются детерминированными. Мы хотим знать производительность алгоритмов в наилучших возможных условиях.Если операционная система по какой-либо причине зависает, это не имеет ничего общего с тем, что мы пытаемся сравнить, поэтому мы должны исключить такие результаты из нашего анализа.
Если бы мы использовали
mean
, то такого рода события сильно исказили бы наши результаты, и если бы мы использовали,max
мы получим только самый экстремальный результат - тот, который наиболее вероятно затронут таким событием.Комментатор также говорит:
Я предполагаю, что мы имеем в виду
dict(zip(...
10k случайных чисел. Это звучит как довольно необычный вариант использования. Имеет смысл, что самые прямые вызовы будут доминировать в больших наборах данных, и я не удивлюсь, если зависания ОС будут доминирующими, учитывая, сколько времени потребуется для запуска этого теста, что еще больше искажает ваши цифры. И если вы используетеmean
илиmax
я бы посчитал ваши результаты бессмысленными.Давайте использовать более реалистичный размер в наших лучших примерах:
И мы видим здесь, что
dict(zip(...
действительно работает быстрее для больших наборов данных примерно на 20%.источник
dict(zip(headList, textList))
& 1,95 \ pm 0,030 мкс для{k: v for k, v in zip(headList, textList)}
. Я бы предложил первый для удобочитаемости и скорости. Очевидно, это получает аргумент min () vs mean () для timeit.min
кажется плохой способ сравнить производительность. Навернякаmean
и / илиmax
были бы гораздо более полезные показатели для реального использования.dict
вызов происходит примерно на 10% быстрее.Попробуй это:
В Python 2 это также более экономно по сравнению с потреблением памяти
zip
.источник
zip
уже экономно расходует память. docs.python.org/3/library/functions.html#zip На самом деле вы можете видеть, чтоsix
используетсяzip
в Python 3 для заменыitertools.izip
в Python 2 pythonhosted.org/six .источник
Вы также можете использовать словарь в Python ≥ 2.7:
источник
Более естественным способом является использование словарного понимания
источник
dict
объект, почему так? Спасибо, чувак.Если вам нужно преобразовать ключи или значения перед созданием словаря, тогда можно использовать выражение генератора . Пример:
Посмотрите код, как Pythonista: Идиоматический Python .
источник
с Python 3.x, для понимания
Больше на понимании вины, здесь есть пример:
источник
Для тех, кто нуждается в простом коде и не знаком с
zip
:Это можно сделать одной строкой кода:
источник
List1
дольше, чемList2
for n in range(len(List1))
происходит анти-паттернЛучшее решение по-прежнему:
Транспонировать это:
источник
Вы можете использовать этот код ниже:
Но убедитесь, что длина списков будет одинаковой. Если длина не одинакова. Затем функция zip перевернет длинную.
источник
У меня было это сомнение, когда я пытался решить проблему, связанную с графами. Проблема, с которой я столкнулся, заключалась в том, что мне нужно было определить пустой список смежности, и я хотел инициализировать все узлы пустым списком, и тогда я подумал, как насчет того, чтобы проверить, достаточно ли это быстро, то есть стоит ли выполнять операцию zip вместо простой пары ключ-значение присваивания. Ведь в большинстве случаев фактор времени является важным ледоколом. Поэтому я выполнил операцию timeit для обоих подходов.
Для n_nodes = 10 000 000 я получаю,
Итерация: 2.825081646999024 Сокращение: 3.535717916001886
Итерация: 5.051560923002398 Сокращение: 6.255070794999483
Итерация: 6.52859034499852 Сокращение: 8.221581164998497
Итерация: 8.683652416999394 Сокращение: 12.599181543999293
Итерация: 11.587241565001023 Сокращение: 15.27298851100204
Итерация: 14.816342867001367 Сокращение: 17.162912737003353
Итерация: 16.645022411001264 Сокращение: 19.976680120998935
После определенного момента вы можете ясно видеть, что итерационный подход на n-м шаге обгоняет время, необходимое для стенографического подхода на n-1-м шаге.
источник
Вот также пример добавления значения списка в вашем словаре
всегда проверяйте, чтобы ваш «Ключ» (list1) всегда был в первом параметре.
источник
Решение как словарь с перечислением:
Решение для цикла с перечислением:
источник
Вы также можете попробовать с одним списком, который является комбинацией двух списков;)
источник
метод без функции почтового индекса
источник