3
dic = {'a':'1','b':'2'}
lis = ['a','b']
for c in lis:
    c = dic[c]
print lis

名单没有改变。我曾预计该列表将更改为['1','2']. 谁能解释一下?

4

4 回答 4

4

不,这不是列表迭代的工作方式。c每次迭代都是一个新对象,如果您更改该对象,则原始列表(谢天谢地!)不会被修改。

如果您确实需要,请使用enumerate()

dic = {'a':'1','b':'2'}
lis = ['a','b']
for i, c in enumerate(lis):
    lis[i] = dic[c]
print lis
于 2013-03-09T13:34:56.597 回答
3

您在迭代中缺少的最重要的事情是将元素分配给 name cc=dic[c]重新绑定c到新对象并且不会更新原始对象。考虑以下演示

>>> for i, c in enumerate(lst):
    print id(c), id(lst[i]),
    c=dic[c]
    print id(c)


4935168 4935168 4934712
4935192 4935192 5496728

因此,尽管在分配列表元素和c引用列表中的同一对象之前,但分配字典的值只会更改引用

注意,这里id只是指引用对象的标识符

请注意,当您更改整个列表时,使用列表理解更容易、更快捷

lst = [dic[e] for e in lst]
['1', '2']

警告不要将变量命名为内置

于 2013-03-09T13:37:37.227 回答
2

尝试使用索引而不是变量...

for i in range(len(li)):
    c = li[i]
    li[i] = dic[c]
print li

另外,永远不要list用作变量名..
或使用enumeratelike

for i, c in enumerate(li):
    li[i] = dic[c]
print li

或列表推导

lis = [dic[c] if c in dic else c for c in lis]

为什么不是你在做什么?
当您使用 时for x in y:x获取对象/项目的值y
因此,如果您更改 的值x,则不会更改 的值y[i]i即您所在的索引。

所以,如果你这样做

>>> y = range(5,10)
>>> for x in y:
    i = y.index(x)
    x += 10
    print i
    print 'Value of x    : %3d, id: %7d' % (x, id(x))
    print 'Value of y[i] : %3d, id: %7d' % (y[i], id(y[i]))
    print '-'*31

你会看到区别

于 2013-03-09T13:34:01.530 回答
2

当你这样做

for c in myList:
    c = something

您正在将名称重新绑定c到任何“某物”,在本例中为dic[c]. 为了让 Python 真正“进入”列表,您必须调用该列表上的一个方法——该方法list.__setitem__()告诉 Python 访问实际的列表对象并改变该列表中的项目,而不是进行简单的变量赋值.

for i, c in enumerate(myList):
    myList.__setitem__(dic[c])

当然,这也可以写成(更 Pythonic):

for i, c in enumerate(myList):
    myList[i] = dic[c]

它看起来像一个变量赋值,但它不是。

于 2013-03-09T13:40:57.240 回答