在python中列出一个可以使用的ints列表

I.P*_*ley 1 python hash

我有一个整数列表,我想用作python词典中的键.我正在缓存一个以int的列表作为输入的函数的结果.我目前的解决方案

list_of_ints = [1,20,3,4]
key = str(sorted(list_of_ints))[1:-1].replace(' ','')
Run Code Online (Sandbox Code Playgroud)

它产生关键'1,3,4,20'.似乎应该有更快/更漂亮/更pythonic的方式来做到这一点.

Ada*_*ith 8

只需使用元组作为键.元组是不可变的和可散列的,因此它们可用作字典键.

list_of_ints = [1, 20, 3, 4]
# tuple(list_of_ints) == (1, 20, 3, 4)

some_dict = {tuple(list_of_ints): "some value", ...}
Run Code Online (Sandbox Code Playgroud)

值得注意的是,他们关心订单,因此[1, 20, 3, 4]不会产生相同的价值[1, 3, 20, 4]

您甚至可以创建一个容器来为您执行此操作.

class MyDict(dict):
    def __getitem__(self, key):
        key = tuple(sorted(key))
        return super().__getitem__(key)
    # similar for pop, get, setdefault, update....

>>> d = MyDict()
>>> d[1,2,3] = 4
>>> d[3,2,1]
4
Run Code Online (Sandbox Code Playgroud)

不要试图自己序列化它.如果你这样做,不要使用字符串操作 - 它太难看了.如果您真诚地感到内存匮乏或者您拥有成千上万的这些记录,那么您可以通过序列化来节省微不足道的空间:

def my_serialize(key_nums: list):
    key_nums = sorted(key_nums)
    base = max(key_nums)
    sum_ = 0
    for power, num in enumerate(key_nums):
        sum_ += base**power * num
    return sum_
Run Code Online (Sandbox Code Playgroud)

这应该给你一个唯一的(难以置信的大!)整数存储,它将在内存中小于元组.如果你能避免它,不要这样做 - 它是非常不透明的.


在你提到的评论中,你不会在密钥中有重复的值,所以frozenset肯定是你正在寻找的.

d = {}
list_of_ints = [1, 20, 3, 4]
d[frozenset(list_of_ints)] = "some value"
Run Code Online (Sandbox Code Playgroud)

frozenset对象是不可变的类似于哈希set的对象.它们与订单无关,并且忽略重复.

  • 如果实现为`frozenset(...)`而不是`tuple(sorted(...))`,那么与命令无关的"容器"可能会更好.话虽如此,你的容器仍然缺少一堆方法 - `.pop`,`.get`,`.setdefault`以及其他我目前都不记得的方法... (2认同)

Mar*_*hyn 5

您还可以创建可哈希列表。

from collections import Iterable

class hash_list(list): 
    def __init__(self, *args): 
        if len(args) == 1 and isinstance(args[0], Iterable): 
            args = args[0] 
        super().__init__(args) 
         
    def __hash__(self): 
        return hash(e for e in self)
Run Code Online (Sandbox Code Playgroud)

现在这有效了:

hash(hash_list(1, 2, 3))
Run Code Online (Sandbox Code Playgroud)

或者

hash(hash_list([1, 2, 3]))
Run Code Online (Sandbox Code Playgroud)

  • @SujalSingh 有时您需要可变且同时可哈希的序列。 (2认同)