【问题标题】:append in a loop, python [duplicate]在循环中追加,python [重复]
【发布时间】:2014-11-19 03:18:11
【问题描述】:

我在列表中追加一个非常奇怪的问题。

import random

def CreatePopulation(a, r):
    pippo=range(a)
    print pippo
    i=0
    prova=[]
    while i<r:
        random.shuffle(pippo)
        print pippo
        prova.append(pippo)
        print prova
        i=i+1
    return prova

pop=CreatePopulation(5,10)
print pop

example=["a","b"]
example.append("c")
print example

我无法上传整个输出,因为网站说它的格式不正确。 但是输出的是一个十倍相同值的列表,x的最后一次shuffle,像这样:

[[1, 0, 4, 2, 3], [1, 0, 4, 2, 3], [1, 0, 4, 2, 3], [1, 0, 4, 2, 3], [1, 0, 4, 2, 3],
 [1, 0, 4, 2, 3], [1, 0, 4, 2, 3], [1, 0, 4, 2, 3], [1, 0, 4, 2, 3], [1, 0, 4, 2, 3],
 [1, 0, 4, 2, 3]]

但循环外的示例可以正常工作:

['a', 'b', 'c']

我真的不明白为什么输出是这样的,而不是在末尾追加,它只是创建一个具有所有相同值的列表。 但是如果我在循环之外使用附加它就可以了。

【问题讨论】:

    标签: python list python-2.7 append


    【解决方案1】:

    代码多次附加同一个列表 (pippo)。

    换句话说,在循环结束时,prova 将包含如下内容:

    prova = [pippo, pippo, pippo, pippo, ..., pippo]
    

    在循环中创建一个新列表将解决问题。

    def CreatePopulation(a, r):
        prova = []
        for i in range(r):
            pippo = range(a)
            random.shuffle(pippo)
            prova.append(pippo)
        return prova
    

    顺便说一句,使用 sample.shuffle 返回一个新列表,您不需要每次都创建一个源列表:

    def CreatePopulation(a, r):
        pippo = range(a)
        return [random.sample(pippo, a) for i in range(r)]
    

    【讨论】:

      【解决方案2】:

      我遇到了同样的问题,并且很难理解为什么会出现此问题。我在互联网上看到的“附加”功能的描述是它“将新项目(对象)附加到数组的末尾”。根据这样的描述,上面的问题肯定不会发生。

      在我看来,“追加”不是将对象添加到列表末尾,而是向该对象添加 reference。因此,当您尝试在循环中使用时,它会一次又一次地添加对内存中同一位置的引用(尽管该位置中的值发生了变化)。因此,您最终会得到 2D 数组,其中每一行都指向内存中的相同位置。

      您可以通过在循环结束后更改 pippo 数组的值来检查这一点:

          def CreatePopulation(a, r):
           pippo=range(a)
           print pippo
           i=0
           prova=[]
           while i<r:
            random.shuffle(pippo)
            print pippo
            prova.append(pippo)
            print 'prova=', prova
            i=i+1
           random.shuffle(pippo) #here we change pippo after appending of prova is done
           return prova
      
          pop=CreatePopulation(5,10)
          print 'pop=', pop
      

      在结果中会有类似的东西:

          prova= [[0, 2, 3, 4, 1], [0, 2, 3, 4, 1], [0, 2, 3, 4, 1], [0, 2, 3, 4, 1], [0, 2, 3, 4, 1], [0, 2, 3, 4, 1], [0, 2, 3, 4, 1], [0, 2, 3, 4, 1], [0, 2, 3, 4, 1], [0, 2, 3, 4, 1]]
          pop= [[2, 0, 1, 3, 4], [2, 0, 1, 3, 4], [2, 0, 1, 3, 4], [2, 0, 1, 3, 4], [2, 0, 1, 3, 4], [2, 0, 1, 3, 4], [2, 0, 1, 3, 4], [2, 0, 1, 3, 4], [2, 0, 1, 3, 4], [2, 0, 1, 3, 4]]
      

      pop 显示的值与循环中的最后一个 prova 不同,因为我们更改了 pippo 其中 prova 指的是。

      我现在明白为什么在循环内创建一个新的 pippo 列表可以解决问题。

      我还没有发现在任何地方都明确解释了这个“附加”引用逻辑,这就是留下这个评论的原因。

      【讨论】:

        猜你喜欢
        • 2014-05-08
        • 2020-10-10
        • 2017-08-24
        • 2022-01-23
        • 1970-01-01
        • 2016-09-13
        • 1970-01-01
        • 2020-09-21
        • 2013-10-31
        相关资源
        最近更新 更多