【问题标题】:Comparing values of a list within a dictionary比较字典中列表的值
【发布时间】:2017-12-20 04:02:54
【问题描述】:

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

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

【问题讨论】:

    标签: python dictionary tuples heap minimum


    【解决方案1】:

    如果您要比较 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 值,它将尝试比较第二个元素。

    【讨论】:

      【解决方案2】:

      下面的代码使用与 Patrick Haugh 的回答类似的策略,除了它还维护您的字典。正如帕特里克的回答一样,我们将幂值放在元组的开头,以便它被堆正确排序。我们将整数键附加到进入堆的元组的末尾,因为我们需要它来删除已被取代的 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]) 调用不是必需的,但它对于测试和调试很有用。

      【讨论】:

        猜你喜欢
        • 2023-01-07
        • 1970-01-01
        • 1970-01-01
        • 2016-01-25
        • 1970-01-01
        • 1970-01-01
        • 2021-03-12
        • 2012-02-21
        • 1970-01-01
        相关资源
        最近更新 更多