【问题标题】:map::lower_bound() equivalent for python's dict class?map::lower_bound() 等效于 python 的 dict 类?
【发布时间】:2017-02-24 03:24:13
【问题描述】:

我正在编写一些代码,要求我获取键的下限(为简单起见,忽略集合中最小键下方的键)。

在 C++ 中,使用 std::map(作为最具可比性的数据类型)我会简单地使用 lower_bound() 来返回迭代器。

我的 Pythonfoo 不是那么好,但我猜测(如果 Python 还没有这样做的方法),这将是对 lambda 函数的一个很好的使用......

检索给定索引的下限键的 Pythonic 方法是什么?

如果问题太抽象,这就是我真正想要做的:

我有一个按日期索引的 Python 字典。我希望能够使用日期来查找字典,并返回与指定键的下限关联的值。

片段如下:

mymap = { datetime.date(2007, 1, 5): 'foo',
          datetime.date(2007, 1, 10): 'foofoo',
          datetime.date(2007, 2, 2): 'foobar',
          datetime.date(2007, 2, 7): 'foobarbar' }

mydate = datetime.date(2007, 1, 7)

# fetch lbound key for mydate from mymap
def mymap_lbound_key(orig):
    pass # return the lbound for the key 

我真的不想遍历密钥,寻找第一个密钥

【问题讨论】:

    标签: python stl


    【解决方案1】:

    Python 的dict 类没有这个功能;你需要自己写。如果键已经排序肯定会很方便,不是吗,所以您可以对它们进行二进制搜索并避免对它们进行迭代?在这种情况下,我会看看blist 包中的sorteddict 类。 http://pypi.python.org/pypi/blist/

    【讨论】:

      【解决方案2】:

      如果您的日期以某种方式超载,它可以比较事物,请查看bisect module

      一个最小整数编码示例:

      from bisect import bisect_left
      
      data = {
          200 : -100,
          -50 : 0,
          51 : 100,
          250 : 200
      }
      
      keys = list(data.keys())
      
      print data[  keys[ bisect_left(keys, -79) ]  ]
      

      【讨论】:

        【解决方案3】:

        当我想要类似于 c++ 地图的东西时,我使用 SortedDict。您可以使用irange 来获取一个迭代器,指向一个给定键是下界的键——我认为这就是std::lower_bound 的工作原理。

        代码:

        from sortedcontainers import SortedDict
        sd = SortedDict()
        sd[105] = 'a'
        sd[102] = 'b'
        sd[101] = 'c'
        
        #SortedDict is sorted on insert, like std::map
        print(sd)
        
        # sd.irange(minimum=<key>) returns an iterator beginning with the first key not less than <key>
        print("min = 100", list(sd.irange(minimum=100)))
        print("min = 102", list(sd.irange(minimum=102)))
        print("min = 103", list(sd.irange(minimum=103)))
        print("min = 106", list(sd.irange(minimum=106)))
        

        输出:

        SortedDict(None, 1000, {101: 'c', 102: 'b', 105: 'a'})
        min = 100 [101, 102, 105]
        min = 102 [102, 105]
        min = 103 [105]
        min = 106 []
        

        【讨论】:

          【解决方案4】:

          仍然不确定“下限”是什么:查询日期之前/之后的最新日期?

          无论如何,由于 dict 不会对其键施加固有顺序,因此您需要不同的结构。将您的密钥存储在某种结构中,使它们保持排序并允许快速搜索。

          最简单的解决方案是将日期排序存储在(日期,值)列表中,然后进行二进制搜索以放大您想要的区域。如果您需要/想要更好的性能,我认为您需要的是 b-tree。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2010-10-22
            • 2017-03-02
            • 2021-07-27
            • 1970-01-01
            • 2010-12-08
            • 2014-05-15
            • 2011-04-30
            • 1970-01-01
            相关资源
            最近更新 更多