代码之家  ›  专栏  ›  技术社区  ›  user1767754

Dict.set默认值插入排序到列表中

  •  3
  • user1767754  · 技术社区  · 6 年前

    我想知道是否有一种方法可以使用类似lambda的样式附加到字典的列表字段。

    例子:

    a = {}
    a.setdefault("foo", []).append(2)
    a.setdefault("foo", []).append(1)
    {'foo': [2, 1]}
    

    有没有办法做一个 insert in sorted order a["foo"].bisect.insort(a, -1) ,这样我以后就不需要再打给sort了?

    3 回复  |  直到 6 年前
        1
  •  2
  •   rocksportrocker    6 年前

    import bisect
    from collections import defaultdict
    
    
    def add(dd, key, value):
        bisect.insort_left(dd[key], value)
    
    
    a = defaultdict(list)
    add(a, "foo", 3)
    add(a, "foo", 2)
    add(a, "foo", 1)
    add(a, "foo", 3)
    add(a, "foo", 2)
    add(a, "foo", 1)
    
    assert a["foo"] == sorted(a["foo"])
    print(a)
    

    如果你想要一个lambda:

    add = lambda dd, key, value: bisect.insort_left(dd[key], value)
    

    sort 运行时应该比使用 bisect.insort_left . 在这两种情况下,运行时的复杂性都很低 O(n对数n) 但是函数调用开销会导致不同的绝对运行时间。

        2
  •  1
  •   Jean-François Fabre    6 年前

    你可以用 collections.defaultdict SortedList 实现(下载时附带 pip install sortedcontainers

    import collections
    from sortedcontainers import SortedList
    
    a = collections.defaultdict(SortedList)
    a["foo"].add(2)
    a["foo"].add(1)
    print(a)
    

    结果:

    defaultdict(<class 'sortedcontainers.sortedlist.SortedList'>, {'foo': SortedList([1, 2])})
    

    你可以重写 add 通过 append

    请注意,它也适用于 setdefault

    a = {}
    a.setdefault("foo", SortedList()).add(2)
    a.setdefault("foo", SortedList()).add(1)
    

    (在许多元素上这样做的缺点是创建 SortedList() 对象,以防密钥不存在)

        3
  •  0
  •   Alan haha    6 年前

    当您可以这样做时,使用助手函数:

    def list_append(lst, item):
        lst.append(item)
        return lst
    
    a = {}
    list_append(a.setdefault("foo", []), 2).sort()
    list_append(a.setdefault("foo", []), 1).sort()
    

    但我绝对建议您尝试其他数据结构,例如 heapq .