2015-08-05 2 views
1

Скажем, у меня есть Dict:python: разница между списком (dict) и dict.keys()?

foo = {'a': 1} 

Оба list(foo) и foo.keys() возвращают то же самое. В чем разница между ними?

+0

В python3 'foo.keys()' возвращает 'view' – NightShadeQueen

+0

Обратите внимание, что вызов' list() 'будет в основном перебирать возвращаемый объект из' __iter__', поэтому, если вы переопределите 'dict'' __iter__ 'в классе, а затем вызывать' .keys() 'и' list() 'на нем, тогда только вызов' list() 'будет запускать новый' __iter__'. –

ответ

7

Отличие заключается в Python 3. foo.keys() возвращает итератор ключей, который является тем, что делает foo.iterkeys() в Python 2, в то время как list(foo) возвращает список ключей.

Как указано ниже, foo.keys() точно не возвращает итератор в Python 3. Он возвращает объект (или представление) dict_keys, который, среди своих операций, допускает итерацию. Вы также можете делать забавные вещи, такие как операции набора и множественная итерация. Он по-прежнему имеет концепцию ленивой оценки, которая делает итераторы такими мощными.

+0

В Python 2 'list (foo)' по существу вызывает 'foo.iterkeys()' и создает список из его содержимого, так как 'foo.iterkeys()' и 'iter (foo)' возвращает тот же объект. – chepner

+0

Да, проверьте документацию также - https://docs.python.org/3/tutorial/datastructures.html - Последний пункт в сносках. 'dict.keys()' возвращает объект просмотра словаря (не итератор). –

3

В python 2 нет реальной разницы, поэтому я подозреваю, что dict.keys изменен, чтобы вернуть представление в python3, и dict.viewkeys был удален.

В Python 3:

In [3]: foo = dict((k,k) for k in range(4)) 

In [4]: foo 
Out[4]: {0: 0, 1: 1, 2: 2, 3: 3} 

In [5]: foo.keys? 
Type:  builtin_function_or_method 
String form: <built-in method keys of dict object at 0x7f45d8667708> 
Docstring: D.keys() -> a set-like object providing a view on D's keys 

In [6]: foo.keys() 
Out[6]: dict_keys([0, 1, 2, 3]) 

In [7]: type(foo.keys()) 
Out[7]: dict_keys 

In [8]: for i in foo.keys(): 
    ...:  del foo[i] 
    ...:  
--------------------------------------------------------------------------- 
RuntimeError        Traceback (most recent call last) 
<ipython-input-8-659d5446ab29> in <module>() 
----> 1 for i in foo.keys(): 
     2  del foo[i] 
     3 

RuntimeError: dictionary changed size during iteration 

In [9]: for i in list(foo): 
    del foo[i] 

In [10]: foo 
Out[10]: {} 

Последние две вещи, в основном то, что вам нужно знать о разнице между dict.keys и list(dictionary) в питона . dict.keys is только вид ключей, поэтому проверка item in dictionary.keys() - это O (1), но вы не можете перебирать более dictionary.keys() и одновременно изменять словарь.

Они оба являются итераторами, поскольку оба они реализуют __iter__.

+0

'list (foo)' дает вам весь новый объект списка, не так ли? Вот почему вы можете удалить элементы из него, я думаю :) – Pynchia

+0

Да, поэтому вы можете перебирать и удалять из словаря. – NightShadeQueen

+0

Что такое обозначение 'foo.keys? '? Кажется, это не работает для меня. – lang2

2

Python3:

от официального documentation

Calling foo.keys() возвращает объект словаря вид. Он поддерживает операции , такие как членский тест и итерация, но его содержимое не зависит от оригинального словаря - это только вид.

на самом деле,

type(foo.keys()) 

дает

<class 'dict_keys'> 

в то время как в Python 2 и

type(list(foo)) 
type(foo.keys()) 

дают

<type 'list'> 
Смежные вопросы