【问题标题】:Tuple-key dictionary in python: Accessing a whole block of entriespython中的元组键字典:访问整个条目块
【发布时间】:2021-11-14 19:28:06
【问题描述】:

我正在寻找一种有效的 python 方法来利用具有两个键的哈希表: 例如:

(1,5) --> {a}
(2,3) --> {b,c}
(2,4) --> {d}

此外,我还需要能够检索整个条目块,例如所有在第 0 位具有“2”的条目(此处:(2,3) 和 (2,4))。 在另一个post 中,建议使用列表理解,即:

sum(val for key, val in dict.items() if key[0] == 'B')

我了解到字典是(可能?)从 key:value-pairs 的对象中检索值的最有效方法。然而,只调用一个不完整的元组键与查询整个键有点不同,我要么得到一个值,要么什么也没得到。我想问一下python是否仍然可以在与匹配的键:值对数量成正比的时间内返回值?或者,元组字典(加上列表理解)是否比使用 pandas.df.groupby() 更好(但这会占用太多内存空间)?

【问题讨论】:

  • 你能用字典吗?所以你会得到{1: {5: {a}}, 2: {3: {b, c}, 4: {d}}},然后你也可以在 O(1) 中得到一个“块”(而不是对你当前正在做的所有键进行 O(n) 扫描)。
  • “但是,只调用一个不完整的元组键与查询整个键有点不同,我要么得到一个值,要么什么也没有。” 这不仅仅是有点不同。这会将查找从恒定时间更改为线性时间(与字典的总长度成正比)。我认为 jonsharpe 有一个很好的建议。
  • 我不愿意使用字典词典。但是在您回答查找正在成为线性时间之后,并且我注意到它比我最初想象的更适合我的代码,我采用了字典方法的字典。谢谢!

标签: python dictionary dictionary-comprehension


【解决方案1】:

“标准”方式类似于

d = {(randint(1,10),i):"something" for i,x in enumerate(range(200))}

def byfilter(n,d):
    return list(filter(lambda x:x==n, d.keys()))

byfilter(5,d) ##returns a list of tuples where x[0] == 5

虽然在类似情况下我经常使用next() 手动迭代,但我不需要完整列表。

但是,我们可能会在某些用例中对其进行优化。假设您需要通过 key first 元素进行几次或多次访问,并且您知道 dict 键同时没有改变。然后你可以提取列表中的键并对其进行排序,并利用一些itertools函数,即dropwhile()takewhile()

ls = [x for x in d.keys()]
ls.sort() ##I do not know why but this seems faster than ls=sorted(d.keys())

def bysorted(n,ls):
    return list(takewhile(lambda x: x[0]==n, dropwhile(lambda x: x[0]!=n, ls)))
bysorted(5,ls) ##returns the same list as above

在最好的情况下(i=1 在我的例子中)这可以快 10 倍,在最坏的情况下(i=10)或多或少花费相同的时间,因为我们正在减少所需的迭代次数。

当然你可以通过x[1]来访问密钥,你只需要在sort()调用中添加一个key参数

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-17
    • 1970-01-01
    • 1970-01-01
    • 2020-05-12
    • 1970-01-01
    • 2018-02-09
    相关资源
    最近更新 更多