it-roy-ru.com

Как вернуть ключи словаря в виде списка в Python?

В Python 2.7 я мог получить словарь ключи, значения или элементы в виде списка:

>>> newdict = {1:0, 2:0, 3:0}
>>> newdict.keys()
[1, 2, 3]

Теперь в Python> = 3. я получаю что-то вроде этого:

>>> newdict.keys()
dict_keys([1, 2, 3])

Итак, я должен сделать это, чтобы получить список:

newlist = list()
for i in newdict.keys():
    newlist.append(i)

Мне интересно, есть ли лучший способ вернуть список в Python?

524
user2015601

Попробуйте list(newdict.keys()).

Это преобразует объект dict_keys в список.

С другой стороны, вы должны спросить себя, имеет ли это значение. Pythonic способ кодирования состоит в том, чтобы предположить типизацию утки (если это похоже на утку, и это крякает как утка, это - утка). Объект dict_keys будет действовать как список для большинства целей. Например:

for key in newdict.keys():
  print(key)

Очевидно, что операторы вставки могут не работать, но это не имеет особого смысла для списка словарных ключей в любом случае.

670
Chris

Python> = 3.5 альтернатива: распаковать в список литерал [*newdict]

Новое распаковка обобщений (PEP 448) было введено с Python 3.5, что теперь позволяет легко выполнять:

>>> newdict = {1:0, 2:0, 3:0}
>>> [*newdict]
[1, 2, 3]

Распаковка с помощью * работает с любым объектом, который является итеративным, и, поскольку словари возвращают свои ключи при повторении, вы можете легко создать список, используя его в литерале списка.

Добавление .keys() i.e [*newdict.keys()] может помочь сделать ваше намерение более явным, хотя это будет стоить вам поиск и вызов функции. (что, честно говоря, это не то, что вы должны действительно беспокоиться).

Синтаксис *iterable аналогичен синтаксису list(iterable), и его поведение было первоначально задокументировано в Раздел вызовов Справочного руководства Python. В PEP 448 ограничение на место появления *iterable было ослаблено, что позволило также размещать его в литералах list, set и Tuple. Справочное руководство по Списки выражений также обновлено, чтобы заявить об этом.


Хотя это эквивалентно 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}

остерегайтесь запятой в случае Tuple!

170
Jim Fasarakis Hilliard

list(newdict) работает в Python 2 и Python 3, предоставляя простой список ключей в newdict. keys() не требуется. (:

26
Seb

Немного оторвано от определения "duck typing" - 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']]
23
Chris Barker

Вы также можете использовать список понимания:

>>> newdict = {1:0, 2:0, 3:0}
>>> [k  for  k in  newdict.keys()]
[1, 2, 3]

Или короче,

>>> [k  for  k in  newdict]
[1, 2, 3]

Примечание: заказ не гарантируется в версиях под 3.7 (заказ по-прежнему только деталь реализации с CPython 3.6).

12

Преобразование в список без использования метода keys делает его более читабельным:

list(newdict)

и при просмотре словарей нет необходимости в keys():

for key in newdict:
    print key

если вы не изменяете его в цикле, для которого потребуется предварительно созданный список ключей:

for key in list(newdict):
    del newdict[key]

В Python 2 предельный прирост производительности при использовании keys().

8
Cas

Если вам нужно хранить ключи отдельно, вот решение, которое требует меньше ввода, чем любое другое решение, представленное до сих пор, с использованием Extended Iterable Unpacking (python3.x +).

newdict = {1: 0, 2: 0, 3: 0}
*k, = newdict

k
# [1, 2, 3]

            ╒═══════════════╤═════════════════════════════════════════╕
            │ k = list(d)   │   9 characters (excluding whitespace)   │
            ├───────────────┼─────────────────────────────────────────┤
            │ k = [*d]      │   6 characters                          │
            ├───────────────┼─────────────────────────────────────────┤
            │ *k, = d       │   5 characters                          │
            ╘═══════════════╧═════════════════════════════════════════╛
6
cs95

Вы также можете сделать Tuple(dict) или set(dict):

>>> list(set(newdict))
[1, 2, 3]
>>> list(Tuple(newdict))
[1, 2, 3]
2
SuperNova

Кроме способов, упомянутых на этой странице, вы можете использовать itemgetter из модуля оператора:

>>> from operator import itemgetter
>>> list(map(itemgetter(0), dd.items()))
[1, 2, 3]
1
SuperNova

список (newdict.keys ())

list(newdict.keys())
0
Sat110