0

Project Eulerを使用してプログラミングを行っていますが、奇妙な問題に遭遇しました。2 つの自然数から (自然) 数を生成するすべての可能な方法を見つけたいと考えています。奇妙な結果に気付いた単純なループを作成しました。たとえば、1 は 3 と 1 から生成されました。調査の結果、次のようになりました。

#Importing stuff I often use in my solutions/tests
from math import sqrt, log, floor, pow, fabs, factorial
from sets import Set
from random import randint
from itertools import permutations
import sys


dub = dict()

c = 0 #Counting the number of elements in dub[18], use to track changes
for i in range (1,10):
    if 18 in dub: #setting c = len(dub[18])
        c = len(dub[18])
    for j in range (i+1,10):
        pair = [[i,j]]
        v = i+j
        if v in dub:
            dub[v].append(pair[0])
        else:
            dub[v] = pair
        v = i*j        
        if v in dub:
            dub[v].append(pair[0])
        else:
            if i == 3 and j == 8: print 'here', v # The value that is added to dub[18] instead of dub[24]
            dub[v] = pair
        if 18 in dub and not c == len(dub[18]): #This is how I found that something is wrong.
            c = len(dub[18])
            print dub[18]
            print v,i,j
            raw_input()

これでどの結果が得られますか:

[[2, 9]]
18 2 9

[[2, 9], [3, 6]]
18 3 6

here 24
[[2, 9], [3, 6], [3, 8]]
24 3 8

私が使用するはずのキーは 24 ですが、リストはキー 18 の下に配置されています。なぜですか?

4

2 に答える 2

7

複数のキーに同じリストを再利用しています。この線

pair = [[i,j]]

単一のペアを含むリストを作成します。このリストは両方のelseブランチで使用されます

else:
    dub[v] = pair

同じリスト オブジェクトを使用して 2 つの異なるキーが生成されます。これは同じオブジェクトであるため、これら 2 つのキーのいずれかのリストへの追加は、もう一方のキーに表示されます。

編集:これは、この動作を示す最小限の例です:

>>> d = {}
>>> a = []
>>> d[0] = a
>>> d[1] = a
>>> d[0].append(2)
>>> d[0]
[2]
>>> d[1]
[2]

明らかな修正は、ペアのみを name に割り当て、pair必要に応じてペアを含む新しいリストを作成することです:

dub = {}
for i in range (1, 10):
    for j in range (i + 1, 10):
        pair = [i, j]
        v = i + j
        if v in dub:
            dub[v].append(pair)
        else:
            dub[v] = [pair]
        v = i * j
        if v in dub:
            dub[v].append(pair)
        else:
            dub[v] = [pair]

このコードをさらに単純化するために、 を次ifのように置き換えることができdict.setdefault()ます。

dub = {}
for i in range (1, 10):
    for j in range (i + 1, 10):
        pair = [i, j]
        dub.setdefault(i + j, []).append(pair)
        dub.setdefault(i * j, []).append(pair)
于 2012-09-09T20:02:13.810 に答える
0

を使用するfromkeysと、この問題も発生します。

data = dict.fromkeys([int(x) for x in row[1:]], [])

解決策は、ディクショナリのデフォルト値を開始するsetdefault代わりに使用しています:fromkeys

data.setdefault(idx, []).append((row[0], val))

于 2016-08-13T04:35:39.883 に答える