Как вернуть ключи словаря в виде списка в 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
объект в список.С другой стороны, вы должны спросить себя, имеет ли это значение. Питонический способ кодирования заключается в том, чтобы предположить, что утка набирает (если он выглядит как утка и крякает как утка, то это утка). Элемент
dict_keys
объект будет действовать как Список для большинства целей. Например:for key in newdict.keys(): print(key)
очевидно, что операторы вставки могут не работать, но это не имеет большого смысла для a список словарных ключей в любом случае.
Python >= 3.5 альтернатива: распаковать в список литерал
[*newdict]
новая распаковка обобщений (PEP 448) были введены с Python 3.5 позволяет теперь легко сделать:
>>> newdict = {1:0, 2:0, 3:0} >>> [*newdict] [1, 2, 3]
распаковка с
*
работает с любой объект, который является итерационным и, поскольку словари возвращают свои ключи при повторении, вы можете легко создать список, используя его в литерале списка.добавить
.keys()
Я.е[*newdict.keys()]
может помочь в создании вашего намерения немного более явным, хотя это будет стоить вам функции поиска и вызова. (что, честно говоря, не то, что вы должны действительно быть обеспокоены).Элемент
*iterable
синтаксис похож на doinglist(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}
остерегайтесь конечной запятой в случае кортежа!
немного выключен на определение "утка набрав"--
dict.keys()
возвращает итерационный объект, а не объект типа списка. Он будет работать везде, где будет работать итерируемый, а не в любом месте списка. список также является итерируемым, но итерируемый не является списком (или последовательностью...)в реальных случаях использования, наиболее распространенная вещь, чтобы сделать с ключами в 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']
лично я считаю это "нарушением" утиного набора текста, а следовательно, и "ошибкой"."Но я предполагаю, что кто-то еще должен был заметить это к настоящему времени, и поэтому, если он не был исправлен, должен считаться "особенностью", но я не могу понять, почему.
добавление в ответ Крису:
хорошо, Крис, ну тогда, по крайней мере, лучше обнаружение неправильного использования и уведомление ("Вы, кажется, не хотите итератор здесь; вы ожидали список? Список попыток(дикт.ключи.))(..") было бы больше похоже на полезного питона, которого я узнал и полюбил. : / (Я бы попросил вас предоставить данные для резервного копирования вашего утверждения о том, что функциональность итератора является "более распространенным" вариантом использования для dict.ключи, но вы, вероятно, сможете их предоставить.);- ) Насколько мой пример понимания списка не работает (для меня), он был вырезан и вставлен из командной строки отладчика PyCharm, поэтому, возможно, проблема в этом. (Я уже сталкивался еще одна "ошибка" в этом сегодня, так что это меня совсем не удивит.) Спасибо!