I am confused how python is iterating through this dictionary. From python's documentation, the itervalues returns an iterator over the dictionary's valu开发者_开发百科es.
dict = {"hello" : "wonderful", "today is" : "sunny", "more text" : "is always good"}
for x in dict.itervalues():
x = x[2:]
print dict
This prints out the original dictionary unchanged. Why is that? If I am saying the value at position x is "blabla", why is it not getting set?
This has nothing to do with strings or lists. The devil is in how the for
is unfolded.
Doing
for x in d.iteritems():
# loop body
is more-or-less equivalent to doing
iter = d.itervalues()
while True:
try:
x = next(iter)
# loop body
except StopIteration:
break
So with this in mind it's not very hard to see that we are just reassigning x
, which holds a result from a function call.
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
The only thing the line
x = x[2:]
does is creating the string slice x[2:]
and rebinding the name x
to point to this new string. It does not change the string x
pointed to before. (Strings are immutable in Python, they can't be changed.)
To achieve what you actually want, you need to make the dictionary entry point to the new string object created by the slicing:
for k, v in my_dict.iteritems():
my_dict[k] = v[2:]
As Sven Marnach points out, strings are immutable and you are just rebinding x
to a new string created by the slice notation. You can demonstrate that x
does point to the same object in the dictionary by using 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)]
You can use iteritems
to iterate over key and value together to do what you want:
for k,v in dict.iteritems():
dict[k] = v[2:]
精彩评论