Як повернути словникові ключі як список у Python?


778

У 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 ?


Цікаве питання безпеки теми щодо цієї теми тут: blog.labix.org/2008/06/27/…
Павло

2
Я новачок у Python, і мені здається, що це розповсюдження марних нових типів даних є одним з найгірших аспектів Python. Для чого використовується цей тип даних dict_keys? Чому б не список?
Філ Гец

Відповіді:


975

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

Це перетворить dict_keysоб’єкт у список.

З іншого боку, ви повинні запитати себе, чи це має значення чи ні. Пітонічним способом кодування є припущення набору тексту качки ( якщо вона схожа на качку, і вона хитається, як качка, це качка ). dict_keysОб'єкт буде діяти як список для більшості цілей. Наприклад:

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

Очевидно, що оператори вставки можуть не працювати, але це не має особливого сенсу для списку ключів словника.


49
newdict.keys () не підтримує індексацію
gypaetus

57
list(newdict)також працює (принаймні, в python 3.4). Чи є причина використовувати .keys()метод?
naught101

46
Примітка: у відладчику pdb> list(newdict.keys()) виходить з ладу, оскільки він стикається з однойменною командою pdb. Використовуйте pdb> !list(newdict.keys())для втечі команд pdb.
Riaz Rizvi

23
@ naught101 Так, .keys()є більш зрозумілим, що відбувається далі.
Фелікс Д.

2
Зауважте, що якщо ви використовуєте список (newdict.keys ()), то ключі не в тому порядку, який ви їх розмістили через хеш-замовлення!
Нейт М

276

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

З Python 3.5 було введено нові розпаковувальні узагальнення (PEP 448), що дозволяють тепер легко робити:

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

Розпаковуючи *роботи з будь-яким об'єктом, який є ітерабельним, і оскільки словники повертають свої ключі під час повторення, ви можете легко створити список, використовуючи його в списку, що знаходиться в прямому списку.

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

*iterableСинтаксис аналогічний робити 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}

остерігайтеся зап'ястя в коробці!


велике пояснення, але , будь ласка , ви можете звернутися на будь-яке посилання , яка описує цей тип «*» newdict синтаксису, я маю в виду , як і чому це повертає ключі від словника тільки для understanding.Thanx
Мухаммад Юнус

1
@MYounas Цей синтаксис був доступний вже досить давно, навіть у Python 2. У функціональних викликах ви можете робити з def foo(*args): print(args)подальшим друком foo(*{1:0, 2:0})результату (1, 2). Така поведінка визначена в розділі Виклики в довідковому посібнику. Python 3.5 з PEP 448 просто послабив обмеження щодо того, де вони можуть з’являтися, дозволяючи [*{1:0, 2:0}]тепер використовувати. У будь-якому випадку я відредагую свою відповідь і включу її.
Димитріс Фасаракіс Хілліард

1
*newdict- це однозначно відповідь для кодових гольфістів; P. Також: що, чесно кажучи, не те, про що ви дійсно повинні турбуватися - і якщо ви є, не використовуйте python .
Артеміда досі не вірить SE

46

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


26

Трохи відключившись від визначення "введення качки" - 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']]

2
Вам навіть не потрібно користуватися .keys(); об'єкт словника є сам ітерацію і виробляє ключі при ітерації: [key.split(", ") for key in d].
Martijn Pieters

25

Ви також можете використати розуміння списку :

>>> 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).


6
Просто використовуйте list(newdict). Тут не потрібно розуміння списку.
Martijn Pieters

8

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

list(newdict)

і, переглядаючи словники, не потрібно keys():

for key in newdict:
    print key

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

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

На Python 2 є граничне збільшення продуктивності використанняkeys() .


8

Якщо вам потрібно зберігати ключі окремо, ось рішення, яке вимагає меншої клавіші тексту, ніж будь-яке інше рішення, представлене до цього часу, використовуючи розширене ітерабельне розпакування (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                          
            ╘═══════════════╧═════════════════════════════════════════╛

1
Єдине незначне застереження, яке я зазначив, - kце завжди список. Якщо користувач захоче кортеж або набір із клавіш, вони повинні повернутися до інших параметрів.
Дімітріс Фасаракіс Хілліард

1
Більш примітним слід зазначити той факт, що, як твердження, *k, = dє обмеження щодо того, де воно може з’являтися (але дивіться, а можливо, оновіть цю відповідь для, PEP 572 - розширене розпакування не підтримується для виразів atm призначення, але це може бути коли-небудь! )
Дімітріс Фасаракіс Хілліард

що робити, якщо ви хочете, щоб і ключі, і значення в списках?
ендоліти

1
@endolith можливо keys, vals = zip(*d.items())(хоча це дає два кортежі, досить близько). Я не знаю коротшого виразу, ніж цей.
cs95

1

Я можу придумати два способи, за допомогою яких ми можемо витягти ключі зі словника.

Спосіб 1: - Отримати ключі методом .keys (), а потім перетворити їх у список.

some_dict = {1: 'one', 2: 'two', 3: 'three'}
list_of_keys = list(some_dict.keys())
print(list_of_keys)
-->[1,2,3]

Спосіб 2: - Створити порожній список, а потім додати ключі до списку за допомогою циклу. Ви також можете отримувати значення за допомогою цього циклу (використовуйте .keys () лише для клавіш та .items () для вилучення ключів і значень)

list_of_keys = []
list_of_values = []
for key,val in some_dict.items():
    list_of_keys.append(key)
    list_of_values.append(val)

print(list_of_keys)
-->[1,2,3]

print(list_of_values)
-->['one','two','three']
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.