1

編集: ケースは閉じられました。解決策については、以下の選択された回答を参照してください(rnorrisに感謝します!)

質問内容は以下。


私は自分の質問についてある程度の洞察を得ました.Pythonで物事を互いに等しく設定する方法についての質問が多いと思いますが、値のみです。私の理解では、最初に子を親と等しく設定してから、必要に応じて変更したいので、問題が発生しています。問題は、私が言うときです

child = parent

それらがメモリ内の同じスペースを参照するようにするため、子の値への変更は親の値への変更になります。値を個別に編集できるようにしながら、子を親と等しく設定する方法はありますか?

元の質問は以下です。


これは、ブール値を使用した私のプロジェクトに関する別の質問です。私のプロジェクトが奇妙な方法で動作している理由を理解しようとしています。非常に長い質問で申し訳ありませんが、あなたが私を助けてくれることを願っています!

私のプロジェクトはグラフ検索をモデル化することであり、私の問題は親と子にあります。どのように機能するかというと、新しい子ノードを生成するために親で実行できる最大 4 つのアクションがあります。「ファーマー」を true から false (またはその逆) に反転し、ファーマーと他の 3 つの bool のいずれかの両方を反転します。 、オオカミ、ヒツジ、キャベツ、ただしそれらがファーマーと等しい場合のみ (つまり、オオカミとファーマーが両方とも true の場合、両方を裏返して新しい子を作成します)。最初の親ノードの場合、4 つの bool はすべて false であるため、イベントごとに 1 つずつ、合計 4 つの子ノードが作成されるはずです。

#boolfliptest

class node:
    def __init__(self):
        self.farmer, self.wolf, self.sheep, self.cabbage = False, False, False, False
        self.parent = None
        self.cost = 0

parent = node()
fchild = node()
schild = node()
wchild = node()
cchild = node()

fchild = parent
fchild.farmer = (True, False)[fchild.farmer]
fchild.parent = parent
fchild.cost += 1

if(parent.farmer == parent.wolf):
    wchild = parent
    wchild.farmer != wchild.farmer
    wchild.wolf != wchild.wolf
    wchild.parent = parent
    wchild.cost += 1

if(parent.farmer == parent.sheep):
    schild = parent
    schild.farmer != schild.farmer
    schild.sheep != schild.sheep
    schild.parent = parent
    schild.cost += 1

if(parent.farmer == parent.cabbage):
    cchild = parent
    cchild.farmer != cchild.farmer
    cchild.cabbage != wchild.cabbage
    cchild.parent = parent
    cchild.cost += 1


print parent.farmer, parent.wolf, parent.sheep, parent.cabbage
print fchild.farmer, fchild.wolf, fchild.sheep, fchild.cabbage
print wchild.farmer, wchild.wolf, wchild.sheep, wchild.cabbage
print schild.farmer, schild.wolf, schild.sheep, schild.cabbage
print cchild.farmer, cchild.wolf, cchild.sheep, cchild.cabbage

親と 4 つの子の 4 つのブール値を出力するために印刷行を使用しているため、これは実際に起こります。それらは次のように表示されます。

    False False False False #parent
    True  False False False #farmer flip only
    True  True  False False #farmer and wolf flip
    True  False True  False #farmer and sheep flip
    True  False False True  #farmer and cabbage flip

しかし、代わりにこれしか得られません:

 % python boolfliptest.py
    False False False False
    False False False False
    False False False False
    False False False False
    False False False False

ブール値を切り替えるために貧弱な方法を使用しているのではないかと思いましたが、どうやら元の方法と同じようにそうでした

schild.farmer != schild.farmer #taken from above

動作しませんでした。fchild Flip ステートメントだけを、ブール値を切り替えるこの新しい方法に置き換えました

fchild.farmer = (True, False)[fchild.farmer]

そして、より良い結果が得られましたが、期待したものではありませんでした. 結果は次のとおりです。

% python boolfliptest.py
True False False False
True False False False
False False False False
False False False False
False False False False

fchild (リストの 2 番目) は予想どおり正しく反転しましたが、親ノードも同様に反転しました。

もう一つやってみました。fchild.farmer bool フリップ行をコメントアウトし、代わりにその新しいメソッドを wchild bool で使用しました。すなわち:

if(parent.farmer == parent.wolf):
    wchild = parent
    wchild.farmer = (True, False)[wchild.farmer]
    wchild.wolf = (True, False)[wchild.wolf]
    wchild.parent = parent
    wchild.cost += 1

この結果も同様に混乱を招きました。wchild のフリッピングは正しく機能しましたが、fchild と親の両方にコピーされており、どちらも変更されていません。

% python boolfliptest.py
True True False False
True True False False
True True False False
False False False False
False False False False

ここで何が起こっているのか誰でも説明できますか? ブール値が奇妙なのはなぜですか?

4

1 に答える 1

2

ここにはいくつかの問題があります。そのうちの 1 つは、次のようにすべてのノードを作成していることです。

parent = node()
fchild = node()
schild = node()
wchild = node()
cchild = node()

ただし、コードの後半には、次のような行があります。

wchild = parent

これはあなたの問題(の一部)だと思います。Python で変数が機能する方法により、変数wchildparent両方が同じオブジェクトを指すようになりました。のフィールドを比較して操作すると、 のフィールドwchildも操作することになりますparent

例として:

parent = node()
wchild = node()
parent.farmer = True
wchild = parent
if wchild.farmer:
  print "Farmer"

「Farmer」を出力する必要があります。

さらに、Python で否定を行うより良い方法は次のようになります。

wchild.wolf = not wchild.wolf

お役に立てれば!

編集:コメントにもう少し明確に答えるために:値を親から子にコピーする場合は、次のnodeようにクラスのメソッドを定義できます。

def copy(self, child_node):
  child_node.farmer = self.farmer

他のフィールドについても同様です。そうすれば、次のようにコピーを作成できます。

parent = node()
child = node()
parent.farmer = True
parent.copy(child)

child.farmerは になりTrue、変更せずに変更できますparent.farmer

于 2013-10-01T22:34:42.977 に答える