2012-09-09 36 views
0

我正在通過Project Euler編程,我遇到了一個奇怪的問題。我想找到所有可能的方法來從兩個自然數中生成(自然)數字。我創建了一個簡單的循環,我注意到了奇怪的結果。例如,從3和1產生1一些調查已經導致本:將值賦給python結果中的字典值爲錯誤的鍵

#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.爲什麼這樣?

回答

7

您正在重複使用多個鍵的相同列表。該行

pair = [[i,j]] 

創建一個包含單個對的列表。該列表在兩個else分支

else: 
    dub[v] = pair 

導致兩個不同的密鑰使用同一列表對象使用。由於它是同一個對象,所以追加到列表中的任何一個都可以在另一箇中看到。

編輯:這裏有一個小例子,證明此行爲:

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

最明顯的解決方法是隻對指定的名稱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] 

爲了進一步簡化該代碼,您可以通過dict.setdefault()更換if S:

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) 
+0

您的解決方案的工作,但我還是不明白。我使用不同的鍵,但我追加到同一個列表中? – Yotam

+0

@Yam:我添加了一個有希望的解釋性例子。 –

+0

@SvenMarmach:謝謝。我現在知道了。 – Yotam

0

如果使用fromkeys,也會導致此問題。

數據= dict.fromkeys([INT(X)爲X [1行:]],[])

該溶液是用setdefault代替fromkeys啓動的默認值字典:

data.setdefault(IDX,[])追加((行[0],VAL))