5

私はまだPythonに少し慣れていませんが、今は本当にばかげていると感じています。なぜなら、このforループが私が望むことをしていない理由を理解するために1時間費やしたからです。forループに1時間を費やすべきではありません。とにかく、私は辞書のリストを生成し、それぞれに一意の番号を付けようとしているので、これを行います...

def initiate(n):
    records = {'num':0,'blah':0,'doubleblah':0}
    x = []
    for i in range(n):
        x.append(records)
        x[i]['num'] = i
    return x

x = initiate(4)
print(x)

関数がこれを返すことを期待しています-

[
 {'num': 0, 'doubleblah': 0, 'blah': 0}, 
 {'num': 1, 'doubleblah': 0, 'blah': 0}, 
 {'num': 2, 'doubleblah': 0, 'blah': 0}, 
 {'num': 3, 'doubleblah': 0, 'blah': 0}
]

しかし、実際にはこれを返します-

[
 {'num': 3, 'doubleblah': 0, 'blah': 0}, 
 {'num': 3, 'doubleblah': 0, 'blah': 0}, 
 {'num': 3, 'doubleblah': 0, 'blah': 0}, 
 {'num': 3, 'doubleblah': 0, 'blah': 0}
]

...関数にいくつかのprintステートメントを追加すると、現在の辞書だけでなく、リスト内のすべての辞書に番号が追加されているように見えることがわかりました。x[i] = i現在の辞書にのみ番号を追加するために明示的に使用しているため、コードがすべての辞書にどのように追加されるかは実際にはわかりません。

4

3 に答える 3

8

何が起こっているのかというと、毎回同じ辞書への参照をリストに追加しているということです。

print list(map(id, initiate(4)))
# [42283920, 42283920, 42283920, 42283920]

関数は次のように正しく記述されています。

def initiate(n):
    return [ {'num': i, 'blah': 0, 'doubleblah': 0} for i in range(n) ]

これにより、毎回辞書の新しいインスタンスが生成されます。

于 2012-10-22T18:05:05.533 に答える
0

ユーザーのテーマに沿って、ここで解決策を説明します。

ただし、dict.copyは浅いコピーであることに注意してください。つまり、そのソースレコードの非プリミティブメンバーが存在する場合、元の問題は存続します。より正確には、この問題はメンバーが可変データ型であることに起因します。整数、文字列、浮動小数点数、ブール値、およびその他のいくつかの組み込み型は不変です。不変性は、オブジェクトが作成されると変更できないことを意味するプロパティです。たとえば、ディクトとリストは変更可能です

def initiate(n, records):
    x = []
    for i in range(n):
        x.append (records.copy())
        x[i]['num'] = i
    return x
    
records = {'num':0,'blah':0,'doubleblah':0}
x = initiate(4, records)

print(x) 
[{'num': 0, 'blah': 0, 'doubleblah': 0}, {'num': 1, 'blah': 0, 'doubleblah': 0}, {'num': 2, 'blah': 0, 'doubleblah': 0}, {'num': 3, 'blah': 0, 'doubleblah': 0}]
[Program finished]
于 2021-03-10T07:23:40.040 に答える
0

これを試して:

def initiate(n):
    my_list = []
    for i in range(n):
        my_list.append(
            {
                'num': i,
                'blah': 0,
                'doubleblah': 0
            }
        )
    
    return my_list
于 2021-03-10T07:36:22.163 に答える