Rumah  >  Soal Jawab  >  teks badan

[Python]list.append()在for循环中每次添加的都是最后的一个元素

迷茫迷茫2714 hari yang lalu544

membalas semua(2)saya akan balas

  • 阿神

    阿神2017-04-17 16:41:44

    首先得知道三点。
    1、程序的运行是需要去内存中申请地址的。
    2、赋值操作只是对于内存中某一块地址的引用。
    3、Python 内置的 id()函数。 该函数从概念上可以理解为得到当前生命下的内存地址。

    id(object)
    Return the “identity” of an object. This is an integer which is guaranteed to be unique and constant for this object during its lifetime. Two objects with non-overlapping lifetimes may have the same id() value.

    CPython implementation detail: This is the address of the object in memory.

    由此我们可以得到以下结果:

    a = 1
    b = 1
    c = a
    d = b
    
    print(id(1))                                       # value x
    print(id(a))                                       # value x
    print(id(b))                                       # value x
    print(id(c))                                       # value x
    print(id(d))                                       # value x
    
    print(id(1) == id(a) == id(b) == id(c) == id(d))   # True

    在此基础上去看 字典/dict :

    当声明一个字典 info = {} 的操作时候,该字典就已经在内存中获取了某一块地址。
    对该字典进行操作时,如 info['name'] = 'github' 的时候,这个字典依旧是之前所占用的地址。
    可通过id 函数跟踪得到以下代码:

    info = {}                       
    print(id(info))                 # value y
    
    info['name'] = 'github'
    print(id(info))                 # value y

    因此,对于你改进前的代码
    pathlist.append(info)添加进去的始终是同一个info,准确的说,始终是同一块地址,而这个info内容在不停的修改。
    参考以下代码:

    info = {'name': 'github'}
    pathlist = [info,]
    
    print(id(info))                 # value z
    print(id(pathlist[0]))          # value z

    然后,对于改进后的代码
    info = {} 的操作放在了循环内,结果就是每一次循环都申请使用一段新的地址,只不过依旧用info来引用。
    可由一下代码对比:

    info = {}
    print(id(info))                 # value m
    
    info = {}
    print(id(info))                 # value n

    两次打印的值是不等的。

    另外
    第一段代码中的
    pathlist.append(info) #将dict添加进list中
    这个注释, 了。

    希望能帮到你。

    balas
    0
  • PHP中文网

    PHP中文网2017-04-17 16:41:44

    原始代码

    listDirectory最终返回的是

    [info, info, info...]

    而info每次循环都会更新,但最终必为

    {'name': last_loop_item}

    所以会有那样的结果

    更新代码

    更新后的代码就比较直观了,
    每次info都是新生成的dict,append的是每次循环产生的结果

    balas
    0
  • Batalbalas