0

技術的背景: Win XP システム上の Python 3.4 + PyGame 1.9.2。

重要

元のタイトルは、Python 辞書の動作とは何の関係もないことが判明したため、誤解を招くものでした! それが辞書で起こったのはただの偶然でした。将来誰かに役立つことを願って、問題を簡単に説明します。

キーとしての位置タプル (x, y) とキーのコンテンツとしてのサーフェスを含む、2 人のプレイヤーの「ボード」 (コンピュータ ゲームとしては一種の戦艦/海戦) を表す 2 つの辞書があります。明確化のための擬似コード:

surface1 = pygame.Surface((w, h)).convert()
surface1.fill(WATER_COLOUR)

dict1 = {(x1, y1): surface1.copy(), (x2, y2): surface1.copy(), (x3, y3): surface1.copy()}
dict2 = dict1.copy()

ゲームの過程で、プレーヤーはディスプレイをクリックし、有効なゲーム フィールドにヒットした場合、船がヒットしたかどうかに応じてそのフィールドの色が変わります。

def clicked(mousepos, key):
    if active_player == 1:
        if mousepos_inside_enemy_ship_rectangle(mousepos):
            dict1[position_of_mouse].fill((255, 0, 0)) # Make it red
        else:
            dict1[position_of_mouse].fill((0, 0, 0)) # Make it black

驚いたことに、両方の辞書ですべての正方形の面の色が変わります! 私は最初、辞書の問題だと思っていましたが、PyGame でサーフェスがどのように機能するかの問題であることがわかりました。

すべての surface1.copy() は、surface1 の 1 つのコピーを参照しているようです。つまり、コピーの 1 つを変更すると、他のすべてのコピーは同じように見えます。実際にはそれをコピーするのではなく、単に参照するだけです。

2 つの解決策があります。

  1. 状態ごとにサーフェスを作成します。1 つは「まだクリックされていない」、もう 1 つは「クリックされたが失敗した」、もう 1 つは「クリックされてヒットした」です。次に、dictionaries キーをそれぞれのサーフェスに変更します。

  2. ディクショナリ内のキーごとに個別のサーフェスを作成し、それぞれの色で個別に塗りつぶします。それも機能します。

解決に尽力してくださった皆様に感謝し、お手数をおかけして申し訳ありません... まったく別の問題です。タイトルとキーワードを更新し、将来誰かに役立つことを願っています. 参照用に古い質問テキストを残しました。そして、その他の辞書の質問へのリンクを追加した人は誰でも:削除してください、それは辞書ではなく表面に関するものです、ありがとう!

パット



古い質問テキスト参照用に残されています

私のスクリプトにはf()、辞書を返す関数があります。

def f(data):
    d = {}
    for n in range(len(data)):
        d.update({n: data[n]})
    return d

まったく同じデータで始まる 2 つの辞書が必要なので、これらのデータをさまざまな方法で変更できます。

dict1 = f(data)
dict2 = dict1.copy()

驚いたことに、同じ変更を変更すると、 !dict1によっても表示されます。dict2コピーはオリジナルから独立していると思っていました - 何か誤解していませんか?

それは間違いなく.copy()方法と関係があります。次のようにコードを変更すると:

dict1 = f(data)
dict2 = f(data)

欲しかったものを正確に受け取り、互いに干渉することなく、両方の辞書を異なる方法で変更できます。

基本的にこれで問題は解決しますが、いくつかの疑問が生じます...何を誤解して.copy()いますか? これは、この Python バージョンの一般的な問題ですか?

//編集:

「変更」の意味を明確にするために:

キーが特定の条件を満たしている場合、dict1 のキーのデータの一部が変更されます。

for key in dict1:
    if key == meets_this_condition:
        dict1[key] = new_data

別の方法では、2 つの辞書の内容を常に比較し、それらが同じか異なるかに応じて特定の関数を呼び出します。

for key in dict1:
    if dict1[key] == dict2[key]:
        do_something()
    else:
        do_something_else()

洞察をありがとう!

パット

4

1 に答える 1

1

私はdeepcopy関数を次のように使用してみます

  dict2=copy.deepcopy(dict1);

コピー ライブラリをインポートする

私が覚えているように、 .copy は浅いコピーを作成して、ポインターのみをコピーします。そのため、場合によっては 1 つを変更すると、コピーも変更されます。

于 2014-09-06T00:04:16.463 に答える