2010-01-03 48 views
3

我正在通過練習Building Skills in Python,據我所知沒有任何發佈的解決方案。學習Python和使用字典

在任何情況下,我都試圖讓字典計算原始列表中某個數字出現的次數,然後再刪除重複項。出於某種原因,儘管下面的主題有很多變化,但我似乎無法增加字典中每個「鍵」的值。

我怎樣才能用字典編碼?

dv = list() 
# arbitrary sequence of numbers 
seq = [2,4,5,2,4,6,3,8,9,3,7,2,47,2] 

# dictionary counting number of occurances 
seqDic = { } 

for v in seq: 
    i = 1 
    dv.append(v) 
    for i in range(len(dv)-1): 
     if dv[i] == v: 
      del dv[-1] 
      seqDic.setdefault(v) 
      currentCount = seqDic[v] 
      currentCount += 1 
      print currentCount # debug 
      seqDic[v]=currentCount 
print "orig:", seq 
print "new: ", dv 
print seqDic 
+0

關於您的代碼:i = 1賦值是錯誤的,並且不會被使用。範圍從0開始,而不是1.範圍(len(dv)-1)中的'-1'也是錯誤的。另外,你應該看看內置的'enumerate',而不是使用範圍(len(dv))。 – 2010-01-03 02:18:13

回答

2

defaultdictdict(它的一個子類,並可以做太多的工作來幫助你,你通過這個練習學會),這裏有一個簡單的方法,用普通dict做到這一點:

dv = list() 
# arbitrary sequence of numbers 
seq = [2,4,5,2,4,6,3,8,9,3,7,2,47,2] 

# dictionary counting number of occurances 
seqDic = { } 

for i in seq: 
    if i in seqDic: 
    seqDic[i] += 1 
    else: 
    dv.append(i) 
    seqDic[i] = 1 

這種簡單的方法在這裏效果特別好,因爲無論如何您都需要if i in seqDic測試來建立dv以及seqDic。否則,簡單的將是:

for i in seq: 
    seqDic[i] = 1 + seqDic.get(i, 0) 

使用便捷的方法dictget,如果第一次沒有在辭典的鍵,返回第二個參數。如果你喜歡這個想法,下面是建立dv的解決方案:

for i in seq: 
    seqDic[i] = 1 + seqDic.get(i, 0) 
    if seqDic[i] == 1: dv.append(i) 

編輯:如果你不dv案例關於項目的順序(而不是想dv是在同一順序項目在seq第一次出現),那麼就使用(循環的簡單版本後)

dv = seqDic.keys() 

也可以(在Python 2,其中.keys返回一個列表),也是如此

dv = list(seqDic) 

這是在兩者的Python 2 Python 3的罰款​​。在相同的假設(即你不關心項目的dv順序)也有其他很好的解決方案,如

seqDic = dict.fromkeys(seq, 0) 
for i in seq: seqDic[i] += 1 
dv = list(seqDic) 

在這裏,我們首先使用字典的fromkeys類方法來建立一個新的字典已經有0作爲每個鍵對應的值,所以我們可以在沒有.get或成員資格檢查等預防措施的情況下遞增每個條目。

+0

+ 1關於OP的好處不是通過使用'defaultdict'來學習。 – bernie 2010-01-03 02:19:07

+1

可能會在字典構建完成後立即構建鍵列表:'dv = list(seq.keys())' – hughdbrown 2010-01-03 02:22:58

+0

@hughdbrown,如果您不關心保存項目的順序,那麼確實是'.keys'是好的(在Python 2中不需要'list()',並且通過使用'print'作爲關鍵字,我們可以推斷出他們正在使用Python 2)。但在這種情況下,還有其他解決方案,讓我編輯A以顯示它們。 – 2010-01-03 16:27:38

2

defaultdict讓一切變得簡單:

>>> from collections import defaultdict 

>>> seq = [2,4,5,2,4,6,3,8,9,3,7,2,47,2] 

>>> seqDic = defaultdict(int) 

>>> for v in seq: 
...  seqDic[v] += 1 

>>> print seqDic 
defaultdict(<type 'int'>, {2: 4, 3: 2, 4: 2, 5: 1, 6: 1, 7: 1, 8: 1, 9: 1, 47: 1}) 
+1

如果你想使用這種方法,你可以使用一組來獲得DV。 – 2010-01-03 02:15:17

+1

+1使用defaultdict。在python 3.0+中,使用collections.Counter。 http://docs.python.org/dev/py3k/library/collections.html – hughdbrown 2010-01-03 02:20:10

2

我真的不知道你嘗試做..怎麼算經常出現的每個數字是什麼?

#arbitrary sequence of numbers 
seq = [2,4,5,2,4,6,3,8,9,3,7,2,47,2] 

#dictionary counting number of occurances 
seqDic = {} 

### what you want to do, spelled out 
for number in seq: 
    if number in seqDic: # we had the number before 
     seqDic[number] += 1 
    else: # first time we see it 
     seqDic[number] = 1 

#### or: 
for number in seq: 
    current = seqDic.get(number, 0) # current count in the dict, or 0 
    seqDic[number] = current + 1 

### or, to show you how setdefault works 
for number in seq: 
    seqDic.setdefault(number, 0) # set to 0 if it doesnt exist 
    seqDic[number] += 1 # increase by one 

print "orig:", seq 
print seqDic 
1

如何:

#arbitrary sequence of numbers 
seq = [2,4,5,2,4,6,3,8,9,3,7,2,47,2] 

#dictionary counting number of occurances 
seqDic = { } 

for v in seq: 
    if v in seqDic: 
     seqDic[v] += 1 
    else: 
     seqDic[v] = 1 

dv = seqDic.keys() 

print "orig:", seq 
print "new: ", dv 
print seqDic 

它的清潔,我認爲這表明你正在努力學習如何以簡單的方式做。像其他人指出的那樣,使用defaultdict可以做到這一點,但知道如何以這種方式做到這一點也是有益的。

+0

+1以獲得比我的更完整的答案,以及上面的'set'註釋。 – bernie 2010-01-03 02:24:20

+1

字典鍵也給你dv。無論如何,如果你正在生成字典,這甚至比使用set更好。 – 2010-01-03 02:28:15

0

或者,如果您使用Python3,則可以使用collections.Counter,它本質上是dict,雖然是分類的。

>>> from collections import Counter 
>>> seq = [2,4,5,2,4,6,3,8,9,3,7,2,47,2] 
>>> Counter(seq) 
Counter({2: 4, 3: 2, 4: 2, 5: 1, 6: 1, 7: 1, 8: 1, 9: 1, 47: 1} 
0
for v in seq: 
    try: 
     seqDic[v] += 1 
    except KeyError: 
     seqDic[v] = 1 

這就是我一直這樣做的內部循環的方式。

除了其他任何東西之外,它在處理元素之前比測試成員要快得多,所以如果你有幾十萬個元素,它會節省很多時間。