Зачем использовать dict.keys?
Недавно я написал код, который выглядел примерно так:
# dct is a dictionary
if "key" in dct.keys():
Однако позже я обнаружил, что я мог бы достичь тех же результатов:
if "key" in dct:
Это открытие заставило меня задуматься, и я начал запускать некоторые тесты, чтобы увидеть, может ли быть сценарий, когда я должен использовать метод keys
словаря. Мой вывод, однако, нет, не существует.
Если мне нужны ключи в списке, я могу сделать:
keys_list = list(dct)
Если я хочу перебирать ключи, я могу сделать:
for key in dct:
...
Наконец, если я хочу проверить, находится ли ключ в dct
, я могу использовать in
, как я уже говорил выше.
Подсчитано, мой вопрос: я что-то упустил? Может ли быть когда-нибудь сценарий, когда я должен использовать метод keys
?... или это просто метод останова из более ранней установки Python, который следует игнорировать?
Ответы
Ответ 1
На Python 3 используйте dct.keys()
, чтобы получить объект просмотра словаря, который позволяет выполнять операции только с ключами:
>>> for sharedkey in dct1.keys() & dct2.keys(): # intersection of two dictionaries
... print(dct1[sharedkey], dct2[sharedkey])
В Python 2 для этого вы должны использовать dct.viewkeys()
.
В Python 2, dct.keys()
возвращает список, копию ключей в словаре. Это может быть передано вокруг отдельного объекта, который можно манипулировать по своему усмотрению, включая удаление элементов, не затрагивающих самого словаря; однако вы можете создать тот же список с list(dct)
, который работает как в Python 2, так и в 3.
Вы действительно не хотите ни одного из них для тестирования итераций или членства; всегда используйте for key in dct
и key in dct
для них соответственно.
Ответ 2
Источник: PEP 234, PEP 3106
Python 2 относительно бесполезный метод dict.keys
существует по историческим причинам. Первоначально, dicts не были итерируемыми. На самом деле не было такого понятия, как итератор; итерации над последовательностями, обработанных вызовом __getitem__
, методом доступа к элементу, с увеличением целочисленных индексов до тех пор, пока не будет поднят IndexError
. Чтобы перебрать ключи dict, вам нужно вызвать метод keys
, чтобы получить явный список ключей и перебрать их.
Когда итераторы вошли, dicts стал повторяемым, потому что было удобнее, быстрее и все вокруг лучше сказать
for key in d:
чем
for key in d.keys()
Это имело побочный эффект, заключающийся в том, что сделать d.keys()
совершенно излишним; list(d)
и iter(d)
теперь сделали все d.keys()
в более чистом, более общем виде. Они не могли избавиться от keys
, хотя, так как много кода уже называли его.
(В это время dicts также получил метод __contains__
, поэтому вы могли бы сказать key in d
вместо d.has_key(key)
. Это было короче и красиво симметрично с for key in d
; симметрия также объясняется тем, почему итерация по dict дает ключи вместо пар (ключ, значение).)
В Python 3, вдохновленном Framework Java Collections Framework, были изменены методы , values
и items
dicts. Вместо того, чтобы возвращать списки, они возвращают представления оригинального dict. Представления ключей и элементов будут поддерживать операции типа типа, и все представления будут обертки вокруг базового dict, отражающие любые изменения в dict. Это сделало keys
полезным снова.
Ответ 3
Предполагая, что вы не используете Python 3, list(dct)
эквивалентен dct.keys()
. Какой из них вы используете, это вопрос личных предпочтений. Я лично считаю, что dct.keys()
немного яснее, но каждому свой.
В любом случае нет сценария, в котором вам "нужно" использовать dct.keys()
как таковой.
В Python 3, dct.keys()
возвращает "объект представления словаря", поэтому, если вам нужно удержать нематериализованный вид ключей (что может быть полезно для огромных словарей) вне контекста контура for
, вам нужно использовать dct.keys()
.