Estoy confundido sobre cómo Python está iterando a través de este diccionario. De la documentación de python, itervalues devuelve un iterador sobre los valores del diccionario.

dict = {"hello" : "wonderful", "today is" : "sunny", "more text" : "is always good"}

for x in dict.itervalues():
    x = x[2:]   

print dict

Esto imprime el diccionario original sin cambios. ¿Porqué es eso? Si digo que el valor en la posición x es "blabla", ¿por qué no se establece?

7
Justin 10 ago. 2011 a las 23:35

3 respuestas

La mejor respuesta

Esto no tiene nada que ver con cadenas o listas. El diablo está en cómo se despliega el for.

Haciendo

for x in d.iteritems():
    # loop body

Es más o menos equivalente a hacer

iter = d.itervalues()
while True:
    try:
        x = next(iter)
        # loop body
    except StopIteration:
        break

Entonces, con esto en mente, no es muy difícil ver que solo estamos reasignando x, que contiene el resultado de una llamada a la función.

iter = d.itervalues()
while True:
    try:
        x = next(iter)

        x = 5 # There is nothing in this line about changing the values of d
    except StopIteration:
        break
7
Emil Ivanov 10 ago. 2011 a las 20:04

Como Sven Marnach puntos fuera, las cadenas son inmutables y solo está volviendo a vincular x a una nueva cadena creada por la notación de corte. Puede demostrar que x apunta al mismo objeto en el diccionario utilizando id:

>>> obj = 'hello'

>>> id(obj)
<<< 4318531232

>>> d = {'key': obj}   

>>> [id(v) for v in d.values()]
<<< [4318531232]

>>> [id(v) for v in d.itervalues()]
<<< [4318531232]

>>> [(k, id(v)) for k, v in d.items()]
<<< [('key', 4318531232)]

>>> [(k, id(v)) for k, v in d.iteritems()]
<<< [('key', 4318531232)]

Puede usar iteritems para iterar sobre la clave y el valor juntos para hacer lo que desee:

for k,v in dict.iteritems():
    dict[k] = v[2:]
1
Community 23 may. 2017 a las 12:32

Lo unico de la linea

x = x[2:]

Lo que hace es crear el segmento de cadena x[2:] y volver a vincular el nombre x para apuntar a esta nueva cadena. No cambia la cadena x señalada anteriormente. (Las cadenas son inmutables en Python, no se pueden cambiar).

Para lograr lo que realmente desea, debe hacer que la entrada del diccionario apunte al nuevo objeto de cadena creado por el corte:

for k, v in my_dict.iteritems():
    my_dict[k] = v[2:] 
5
Emil Ivanov 11 ago. 2011 a las 05:12