0

我试图转换列表中所有元素的类型:

class Dict1(dict):
    pass
class Dict2(dict):
    pass
def print_type(alist):
    for i in range(len(alist)):
        print(type(alist[i]))
l=[]
for i in range(3):
    l.append(Dict1())


for element in l:
    element=Dict2(element)
print_type(l)


for i in range(len(l)):
    l[i]=Dict2(l[i])
print_type(l)

输出:

<class '__main__.Dict1'>
<class '__main__.Dict1'>
<class '__main__.Dict1'>
<class '__main__.Dict2'>
<class '__main__.Dict2'>
<class '__main__.Dict2'>

当我使用时for element in l,元素的类型不会转换为 Dict2,但是,for i in range(len(l))可以做到这一点。

谁能告诉我这是什么原因?

4

2 回答 2

1

for element in l:
    element=Dict2(element)

element只是一个在列表中保存元素的变量。重新分配它只会改变element正在查看的内容,而不是循环中的元素所持有的内容。

这类似于a此处的 never changed:

a = 1
element = a
element = 2

print(a, element)  # 1 2

重新分配变量对碰巧正在查看同一对象的其他代码没有影响。

那么,为什么索引会按您的预期进行呢?因为索引会改变列表本身。

l[i]=Dict2(l[i])

实际上本质上是

l.__setitem__(i, Dict2(l[i]))

它看起来像第一个一样简单的重新分配,但它实际上是一个改变列表本身内容的可变操作。

于 2020-02-07T23:58:54.570 回答
1

这将创建一个包含 3 个类型元素的列表Dict1

l=[]
for i in range(3):
    l.append(Dict1())

但是,当您运行时:

for element in l:
    element=Dict2(element)

...分配element=Dict2(element)不会改变其l自身的内容。在这里,您只是根据对象的内容创建了一个名为的新对象,但这并不会像这样更新变量。elementDict1element

因此:

print_type(l)

打印列表的原始内容l,其元素与Dict1第一个循环中指定的一样。

第二个循环:

for i in range(len(l)):
    l[i]=Dict2(l[i])

实际上使用实际对象分配/更新列表中的一项,通过变量l索引。列表已更新,因此它显示object 而不是.iDict2Dict2Dict1

于 2020-02-07T23:59:38.910 回答