非常奇怪的Python变量范围行为

时间:2011-12-31 00:53:13

标签: python arrays function scope

我遇到了Python 2.7的问题,这让我感到疯狂。

我将一个数组传递给某些函数,并且该变量被置于本地,最后main中变量的值被更改。

我对Python有点新鲜,但这违背了我的常识。

我做错了什么想法?

def mutate(chromo):
    # chooses random genes and mutates them randomly to 0 or 1
    for gene in chromo:
        for codon in gene:
            for base in range(2):
                codon[randint(0, len(codon)-1)] = randint(0, 1)
    return chromo

def mate(chromo1, chromo2):
    return mutate([choice(pair) for pair in zip(chromo1, chromo2)])


if __name__ == '__main__':
    # top 3 is a multidimensional array with 3 levels (in here I put just 2 for simplicity)
    top3 = [[1, 0], [0, 0], [1, 1]]

    offspring = []
    for item in top3:
        offspring.append(mate(top3[0], item))

    # after this, top3 is diferent from before the for cycle

更新 因为Python通过引用传递,所以我必须在使用它们之前对数组进行真正的复制,因此配合函数必须更改为:

import copy
def mate(chromo1, chromo2):
    return mutate([choice(pair) for pair in zip(copy.deepcopy(chromo1), copy.deepcopy(chromo2))])

3 个答案:

答案 0 :(得分:2)

你遇到的问题源于python中的数组和字典是通过引用传递的。这意味着不是由def创建的新副本而是在本地使用,而是在内存中获得指向数组的指针...

x = [1,2,3,4]

def mystery(someArray):
     someArray.append(4)
     print someArray

mystery(x)
[1, 2, 3, 4, 4]

print x
[1, 2, 3, 4, 4]

答案 1 :(得分:1)

您操纵chromo,您通过引用传递。因此,这些变化具有破坏性...... return因此也是如此(codon位于genegene位于chromo)。我认为你需要制作chromos的{​​深层]副本。

答案 2 :(得分:0)

尝试更改

offspring.append(mate(top3 [0],item))to offspring.append(mate(top3 [0] [:],item [:]))

或使用list()函数