2017-07-15 116 views
1

對於背景,我試圖創建一個例程,將我的前50個值存儲在字典中,並且一次以50個值開始,用我找到的任何更好的值替換最小值。比較字典中的列表的值

我想弄清楚如何比較字典裏面使用的元組值。

該字典包含一個int作爲鍵,然後是一個x,y,z座標和與該位置關聯的功率值的元組。所以這樣的事情:

int = 1    #all of these values will change with every iteration or new element 
x_pos = 10.0 
y_pos = 20.0 
z_pos = 30.0 
power = 9000.0 

dictTop50[int] = (x_pos,y_pos,z_pos,power) 

我試過的是用堆來從我的字典中獲得最低值,但我想我可能會做錯了。此外,我不完全確定我將如何將我發現的新值與我的字典中已有的新值進行比較,然後替換這些值。這是我嘗試在那:

if (len(dictTop50) <= 50): 
    dictTop50[int] = (x_pos, y_pos, z_pos, power) 
elif (new power value bigger than any of the 50 other power values): 
    del dictTop50[heapq.nsmallest(1, dictTop50(), key=itemgetter(1))] 
    dictTop50[int] = (x_pos, y_pos, z_pos, power) 

在僞代碼:

if dictionary has 50 or less entries: 
    just add new value to the dictionary 
else if dictionary has more than 50 entries already and new value is greater than present value: 
    delete the dictionary entry with smallest power value 
    add new dictionary element with the highest power value 

對不起,這是很長,但我已經通過堆棧溢出許多其他問題,梳理並不能找到一個解決辦法還。任何建議將不勝感激!

回答

1

以下代碼對Patrick Haugh的答案使用了類似的策略,只是它也保留了您的字典。正如在帕特里克的回答中,我們把功率值放在元組的起始位置,這樣它就可以通過堆正確排序。我們將整數鍵附加到進入堆的元組末尾,因爲我們需要它刪除已被取代的字典項。

一旦達到所需的尺寸限制,我們只需要檢查當前最小的物品。如果最小項目小於新項目,則會被替換。

要測試update代碼,我創建了一個生成器,datagen,它會生成假數據。爲了保持輸出管理,我已經減少了尺寸的前20名,而不是一個50強

from random import seed, randint 
from heapq import heappush, heapreplace 

seed(42) 

# Make some fake data, in this form: (power, x_pos, y_pos, z_pos) 
def datagen(): 
    m = (100., 1., 1., 1.) 
    while True: 
     yield tuple(randint(1, 100) * u for u in m) 

top20 = {} 
heap = [] 

# Update the heap & the dict 
def update(k, tup): 
    if len(top20) < 20: 
     heappush(heap, tup + (k,)) 
     top20[k] = tup 
    elif tup[0] > heap[0][0]: 
     old = heapreplace(heap, tup + (k,)) 
     top20[k] = tup 
     del top20[old[-1]] 
     print('replaced', old[0]) 

# Test 

for k, tup in zip(range(50), datagen()): 
    print(k, tup) 
    update(k, tup) 

輸出

0 (8200.0, 15.0, 4.0, 95.0) 
1 (3600.0, 32.0, 29.0, 18.0) 
2 (9500.0, 14.0, 87.0, 95.0) 
3 (7000.0, 12.0, 76.0, 55.0) 
4 (500.0, 4.0, 12.0, 28.0) 
5 (3000.0, 65.0, 78.0, 4.0) 
6 (7200.0, 26.0, 92.0, 84.0) 
7 (9000.0, 70.0, 54.0, 29.0) 
8 (5800.0, 76.0, 36.0, 1.0) 
9 (9800.0, 21.0, 90.0, 55.0) 
10 (4400.0, 36.0, 20.0, 28.0) 
11 (9800.0, 44.0, 14.0, 12.0) 
12 (4900.0, 13.0, 46.0, 45.0) 
13 (7800.0, 34.0, 6.0, 94.0) 
14 (5900.0, 69.0, 16.0, 49.0) 
15 (1100.0, 71.0, 38.0, 81.0) 
16 (8000.0, 47.0, 74.0, 25.0) 
17 (9100.0, 9.0, 6.0, 85.0) 
18 (3000.0, 99.0, 38.0, 11.0) 
19 (3000.0, 13.0, 49.0, 36.0) 
20 (5900.0, 82.0, 47.0, 21.0) 
replaced 500.0 
21 (4800.0, 46.0, 27.0, 86.0) 
replaced 1100.0 
22 (3500.0, 90.0, 88.0, 83.0) 
replaced 3000.0 
23 (1000.0, 78.0, 82.0, 22.0) 
24 (6900.0, 94.0, 32.0, 21.0) 
replaced 3000.0 
25 (6000.0, 49.0, 35.0, 82.0) 
replaced 3000.0 
26 (8900.0, 72.0, 29.0, 88.0) 
replaced 3500.0 
27 (4200.0, 99.0, 100.0, 8.0) 
replaced 3600.0 
28 (3000.0, 5.0, 41.0, 52.0) 
29 (3500.0, 9.0, 28.0, 73.0) 
30 (9200.0, 41.0, 28.0, 84.0) 
replaced 4200.0 
31 (6400.0, 51.0, 83.0, 59.0) 
replaced 4400.0 
32 (1900.0, 34.0, 18.0, 32.0) 
33 (9600.0, 72.0, 69.0, 34.0) 
replaced 4800.0 
34 (9600.0, 75.0, 55.0, 75.0) 
replaced 4900.0 
35 (5200.0, 47.0, 29.0, 18.0) 
36 (6600.0, 64.0, 12.0, 97.0) 
replaced 5800.0 
37 (700.0, 15.0, 20.0, 81.0) 
38 (2100.0, 88.0, 55.0, 77.0) 
39 (900.0, 50.0, 49.0, 77.0) 
40 (6000.0, 68.0, 33.0, 71.0) 
replaced 5900.0 
41 (200.0, 88.0, 93.0, 15.0) 
42 (8800.0, 69.0, 97.0, 35.0) 
replaced 5900.0 
43 (9900.0, 83.0, 44.0, 15.0) 
replaced 6000.0 
44 (3800.0, 56.0, 21.0, 59.0) 
45 (100.0, 93.0, 93.0, 34.0) 
46 (6500.0, 98.0, 23.0, 65.0) 
replaced 6000.0 
47 (1400.0, 81.0, 39.0, 82.0) 
48 (6500.0, 78.0, 26.0, 20.0) 
replaced 6400.0 
49 (4800.0, 98.0, 21.0, 70.0) 

print('replaced', old[0])通話是沒有必要的,但它是用於測試和調試。

2

如果您要比較power值,那麼您可以使用一堆元組,其中每個元組的第一個值是power值。類似於

import heapq 

def push_keep_fifty(heap, new): 
    if len(heap) < 50: 
     heapq.heappush(heap, new) 
    elif new > heap[0]: 
     heapq.heapreplace(heap, new) 

i = 1 #don't use int as a variable name 
x_pos = 10.0 
y_pos = 20.0 
z_pos = 30.0 
power = 9000.0 

heap = [] 
push_keep_fifty(heap, (power, i, x_pos, y_pos)) 

這是可行的,因爲Python通過比較第一個元素來比較元組,這就是我們想要比較的。請記住,如果兩個元組共享一個power值,它將嘗試比較第二個元素。

+0

@TessellatingHeckler good catch –