2010-09-01 20 views
38

Si entiendo correctamente, en Python 2, iter(d.keys()) era lo mismo que d.iterkeys(). Pero ahora, d.keys() es una vista, que se encuentra entre la lista y el iterador. ¿Cuál es la diferencia entre una vista y un iterador?Iteración de elementos de diccionario(), values ​​(), keys() en Python 3

En otras palabras, en Python 3, ¿cuál es la diferencia entre

for k in d.keys() 
    f(k) 

y

for k in iter(d.keys()) 
    f(k) 

Además, ¿cómo estas diferencias se muestran en un simple bucle for (en su caso)?

Respuesta

53

No estoy seguro de si esta es una buena respuesta a sus preguntas, pero espero que explique un poco sobre la diferencia entre Python 2 y 3 en este sentido.

En Python 2, iter(d.keys()) y d.iterkeys() no son equivalentes, aunque se comportarán de la misma manera. En la primera, keys() devolverá una copia de la lista del diccionario de llaves y iter A continuación, devolver un objeto iterador sobre esta lista, con la segunda copia de la lista completa de teclas que nunca se construyó.

La vista de objetos devueltos por d.keys() en Python 3 son iterables (es decir, un iterador se puede hacer de ellos) así que cuando usted dice for k in d.keys() Python va a crear el iterador para usted. Por lo tanto, sus dos ejemplos se comportarán de la misma manera.

La importancia en el cambio del tipo de cambio de keys() es que el objeto de vista Python 3 es dinámica. es decir, si decimos ks = d.keys() y luego añadimos a continuación dks así lo manifiesta. En Python 2, keys() devuelve una lista de todas las claves actualmente en el dict. Compare:

Python 3

>>> d = { "first" : 1, "second" : 2 } 
>>> ks = d.keys() 
>>> ks 
dict_keys(['second', 'first']) 
>>> d["third"] = 3 
>>> ks 
dict_keys(['second', 'third', 'first']) 

Python 2.x

>>> d = { "first" : 1, "second" : 2 } 
>>> ks = d.keys() 
>>> ks 
['second', 'first'] 
>>> d["third"] = 3 
>>> ks 
['second', 'first'] 

Como keys() retornos de Python 3 del objeto dinámico Python 3 no tiene (y no tiene necesidad de) un método separado iterkeys.

más aclaraciones

En Python 3, keys() devuelve un objeto dict_keys pero si lo usamos en un contexto for bucle for k in d.keys() entonces un iterador se crea implícitamente. Entonces la diferencia entre for k in d.keys() y for k in iter(d.keys()) es una creación implícita vs. explícita del iterador.

En cuanto a la otra diferencia, mientras que son a la vez dinámico, recuerde que si creamos un iterador explícita entonces sólo puede ser usado una vez, mientras que la vista se puede reutilizar como sea necesario. p.ej.

>>> ks = d.keys() 
>>> 'first' in ks 
True 
>>> 'second' in ks 
True 
>>> i = iter(d.keys()) 
>>> 'first' in i 
True 
>>> 'second' in i 
False    # because we've already reached the end of the iterator 

Además, observe que si creamos un iterador explícita y luego modificar el dict entonces el iterador se invalida:

>>> i2 = iter(d.keys()) 
>>> d['fourth'] = 4 
>>> for k in i2: print(k) 
... 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
RuntimeError: dictionary changed size during iteration 

En Python 2, dado el comportamiento actual de keys se necesitaba un método separado para proporcionar una forma de iterar sin copiar la lista de teclas mientras se mantiene la compatibilidad con versiones anteriores. Por lo tanto, iterkeys()

+5

hay '.viewkeys()' en 2.7. que devuelve la vista. http://docs.python.org/library/stdtypes.html#dict.viewkeys – phadej

+0

Gracias. Entiendo cómo 'd.keys()' de Python 2 es diferente. Pero todavía estoy confundido en cuanto a la diferencia entre 'd.iterkeys()' de Python 2, 'd.keys()' de Python 3, y 'iter (d.keys())' de Python 3. Como lejos según tengo entendido, todos son dinámicos, y ninguno de ellos construye la lista por adelantado. – max

+0

En el bucle 'for' no hay diferencia entre' iter (d.keys()) 'y' d.keys() ', ya que python llama internamente a' iter'. Tampoco hay diferencia entre python 2.x 'd.iterkeys()' y py3k 'iter (d.keys())': ambos devuelven dictionary-key-iterator. Entonces los tres son prácticamente lo mismo. – phadej

Cuestiones relacionadas