比较字典中列表的值

时间:2017-07-15 00:43:42

标签: python dictionary tuples heap minimum

对于背景,我正在尝试创建一个例程,将我的前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

对不起,这很长,但我已经梳理了很多关于堆栈溢出的其他问题,但还是找不到解决方案。任何建议将不胜感激!

2 个答案:

答案 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值,它将尝试比较第二个元素。

答案 1 :(得分:1)

下面的代码使用与Patrick Haugh的答案类似的策略,除了它还维护你的字典。正如在Patrick的回答中,我们将幂值放在元组的开头,以便它由堆正确排序。我们将整数键附加到进入堆的元组的末尾,因为我们需要它来删除已被取代的dict项。

一旦达到所需的尺寸限制,我们只需要检查当前最小的项目。如果该最小项目小于新项目,则会被替换。

为了测试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])调用不是必需的,但它对测试和调试很有用。