Как вернуть ключи словаря в виде списка в Python?
на Python 2.7, я мог бы сделать словарь ключи, значения или предметы список:
>>> newdict = {1:0, 2:0, 3:0}
>>> newdict.keys()
[1, 2, 3]
Теперь, Python >= 3.3, я получаю что-то вроде этого:
>>> newdict.keys()
dict_keys([1, 2, 3])
Так, я должен сделать это, чтобы получить список:
newlist = list()
for i in newdict.keys():
newlist.append(i)
мне интересно, есть ли лучший способ вернуть список в Python 3?
9 ответов
попробовать list(newdict.keys())
.
это преобразует dict_keys
объект списка.
С другой стороны, вы должны спросить себя, имеет ли это значение. Питонический способ кода-предположить, что duck typing (если оно выглядит как утка и крякает как утка, это утка). The dict_keys
объект будет действовать как Список для большинства целей. Например:
for key in newdict.keys():
print(key)
очевидно, операторы вставки могут не работать, но это не имеет большого смысла для список ключей словаря в любом случае.
Python >= 3.5 альтернатива: распаковать в список литерал [*newdict]
новая распаковка обобщений (PEP 448) были введены с Python 3.5, что позволяет теперь легко сделать:
>>> newdict = {1:0, 2:0, 3:0}
>>> [*newdict]
[1, 2, 3]
распаковка с *
работает с любой объект, который является итерационным, и, поскольку словари возвращают свои ключи при итерации, вы можете легко создать список, используя его в литерале списка.
добавить .keys()
Я.е [*newdict.keys()]
может помочь в создании вашего намерения немного более явным, хотя это будет стоить вам функции поиска и вызова. (что, честно говоря, не то, что вы должны действительно быть обеспокоены).
The *iterable
синтаксис похож на doing list(iterable)
и его поведение было первоначально задокументировано в раздел звонки справочного руководства Python. С PEP 448 ограничение на где *iterable
может появиться ослаблено позволяя ему также помещаться в литералы списка, набора и кортежа, справочное руководство по списки выражение также был обновлен, чтобы заявить об этом.
хотя, эквивалентной list(newdict)
С той разницей, что это быстрее (по крайней мере, для небольших словарей), потому что вызов функции фактически не выполняется:
%timeit [*newdict]
1000000 loops, best of 3: 249 ns per loop
%timeit list(newdict)
1000000 loops, best of 3: 508 ns per loop
%timeit [k for k in newdict]
1000000 loops, best of 3: 574 ns per loop
С большими словарями скорость почти такая же (накладные расходы на итерацию через большую коллекцию превышают небольшая стоимость вызова функции).
аналогичным образом вы можете создавать кортежи и наборы словарных ключей:
>>> *newdict,
(1, 2, 3)
>>> {*newdict}
{1, 2, 3}
остерегайтесь конечной запятой в случае кортежа!
немного выключено определение "duck typing"-- dict.keys()
возвращает итерируемый объект, а не список, как объект. Он будет работать в любом месте, где будет работать iterable , а не в любом месте списка. список также является итерируемым, но повторяемое не список (или последовательности...)
в реальных случаях использования самое распространенное, что нужно сделать с ключами в dict, - это перебирать их, поэтому это имеет смысл. И если они вам нужны как список, вы можете позвонить list()
.
очень похоже на zip()
-- в подавляющем большинстве случаев он повторяется - зачем создавать целый новый список кортежей, чтобы просто повторить его, а затем снова выбросить?
Это часть большой тенденции в python использовать больше итераторов (и генераторов), а не копии списков повсюду.
dict.keys()
должен работать с пониманием , хотя-тщательно проверьте опечатки или что-то еще... он отлично работает для меня:
>>> d = dict(zip(['Sounder V Depth, F', 'Vessel Latitude, Degrees-Minutes'], [None, None]))
>>> [key.split(", ") for key in d.keys()]
[['Sounder V Depth', 'F'], ['Vessel Latitude', 'Degrees-Minutes']]
list(newdict)
работает как в Python 2, так и в Python 3, предоставляя простой список ключей в newdict
. keys()
не нужно. (:
вы также можете использовать понимание:
>>> newdict = {1:0, 2:0, 3:0}
>>> [k for k in newdict.keys()]
[1, 2, 3]
преобразование в список без использования keys
метод делает его более читабельным:
list(newdict)
и при циклическом просмотре словарей нет необходимости в keys()
:
for key in newdict:
print key
если вы не изменяете его в цикле, который потребует списка ключей, созданных заранее:
for key in list(newdict):
del newdict[key]
на Python 2 существует предельный прирост производительности с использованием keys()
.
кроме способов, упомянутых на этой странице, вы можете использовать itemgetter
из модуля оператора:
>>> from operator import itemgetter
>>> list(map(itemgetter(0), dd.items()))
[1, 2, 3]
вы также можете сделать tuple(dict)
или set(dict)
:
>>> list(set(newdict))
[1, 2, 3]
>>> list(tuple(newdict))
[1, 2, 3]
кроме того, понимание списка, похоже, не работает:
>>> parsed_results.keys()
dict_keys(['Sounder V Depth, F', 'Vessel Latitude, Degrees-Minutes'])
>>> things2plot = [key.split(', ') for key in parsed_results.keys()]
>>> things2plot
['Sounder V Depth', 'F']
>>> for key in parsed_results.keys():
... print(key.split(', '))
...
['Sounder V Depth', 'F']
['Vessel Latitude', 'Degrees-Minutes']
лично я считаю это "нарушением" ввода утки и, следовательно, "ошибкой"."Но я предполагаю, что кто-то еще должен был заметить это сейчас, и поэтому, если это не было исправлено, должно рассматриваться как "особенность", но я не могу понять, почему.
добавление в ответ Крису:
хорошо, Крис, ну тогда, по крайней мере, лучше обнаружение неправильного использования и уведомление ("Вы, похоже, не хотите итератор здесь; вы ожидали список? Попробуйте list(dict.ключи.))(..") было бы больше похоже на полезного питона, которого я узнал и полюбил. : / (Я бы попросил вас данные для резервного копирования вашего утверждения о том, что функциональность итератора является "более распространенным" вариантом использования для dict.ключи, но вы, вероятно, сможете их предоставить.);- ) Насколько мой пример понимания списка не работает (для меня), он был вырезан и вставлен из командной строки отладчика PyCharm, поэтому, возможно, проблема в этом. (Я уже сталкивался еще одна "ошибка" в этом сегодня, так что это не удивило бы меня вообще.) Спасибо!