2011-12-31 102 views
0

我遇到了一个Python 2.7的问题,令我疯狂。非常奇怪的Python变量范围行为

我正在向一些函数传递一个数组,并且尽管变量被认为是本地变量,但最终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 

UPDATE 因为Python经过参考,我一定要在使用前阵列FO一个真正的副本,所以队友功能必须改成:

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

的可能的简短的回答是有在Python中没有“变量”,只有“名字”,这基本上意味着一切都是通过引用,甚至序列中的项目。 – 2011-12-31 00:56:45

+0

是的,我现在改变了。谢谢:) – jbssm 2011-12-31 00:57:42

+0

@jbssm:另外,请不要使用'from random import *'。出于充分的理由,这被认为是不好的做法 – 2011-12-31 00:59:50

回答

1

你操纵chromo,你通过引用传递。因此,这些更改具有破坏性...因此return也是有意义的(codongenegenechromo)。我认为你需要制作一份chromos的(深)副本。

+0

谢谢。所以,我需要在调用** mate **函数或另一个地方之前在** for循环中创建一个TMP副本? – jbssm 2011-12-31 01:06:52

+0

我会在mutate函数中创建一个副本,这样你就可以保留你的结构,并且“返回”变得有意义。 – Nicolas78 2011-12-31 01:08:52

+0

好吧,在变异中出现了一些奇怪的现象:过了一段时间,我所有的向量都是相同的。 所以我把副本移到了队友身上(使用'copy.deepcopy()'例程,它现在似乎正常工作。 – jbssm 2011-12-31 01:22:41

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] 
+0

嗯,好吧,我应该在for循环中创建数组的副本?像:'对于top3中的项目: top3_tmp = top3 [0],itemTmp =项目 offspring.append(mate(top3_tmp,itemTmp))' – jbssm 2011-12-31 01:04:29

0

尝试改变

offspring.append(队友(TOP3 [ 0],项))至 offspring.append(伴侣(TOP3 [0] [:]项[:]))

,或者使用list()函数

+0

使用[:]它不起作用。我会看看我是否可以使用list() – jbssm 2011-12-31 01:13:22