2011-12-31 6 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では "変数"はなく、基本的にすべてが参照渡しであることを意味する "名前"だけであり、シーケンス内の項目でさえあります。 –

+0

はい、今変更しました。ありがとう:) – jbssm

+0

@jbssm:また、 'from random import *'を使用しないでください。これは良い理由のために悪い習慣とみなされます。 –

答えて

1

chromo、これは参照渡しです。したがって、変更は破壊的です... returnは、したがって、やっかいなものです(codongeneで、genechromoです)。あなたはchromosの(深い)コピーを作成する必要があります、と私は思います。

+0

ありがとうございます。ですから、** mate **関数を呼び出す前に** for **ループでTMPコピーを作成する必要がありますか? – jbssm

+0

私はmutate関数でコピーを作成して構造体を保つことができるので、 "return"は意味があります。 – Nicolas78

+0

突然変異の中で何か変わったことがありました。しばらくすると、私のすべてのベクトルは同じになります。 私はコピーを 'copy.deepcopy()'ルーチンを使って移動しましたが、今は正しく動作しているようです。 – jbssm

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

ああ、私のアレイのコピーをどこのループで作るべきですか?のような: 'top3の項目の場合: top3_tmp = top3 [0]、itemTmp = item offspring.append(mate(top3_tmp、itemTmp))' – jbssm

0

offspring.append(メイト(TOP3を[変更してみてください0] offspring.append(嵌合する、項目))(TOP3 [0] [:]、項目[:]))

または使用リスト()関数

+0

[:]では動作しません。私はリストでそれを行うことができるかどうかを見ます() – jbssm