Python 在defaultdict中查找最近的键

Python 在defaultdict中查找最近的键,python,defaultdict,Python,Defaultdict,我使用defaultdicts存储值列表,其中键是可以观察值的时段。 从所有感兴趣期间的列表中查找时,我希望在defaultdict中找到最近的期间(注意:并非所有期间都存储在defaultdict中) 但是,由于defaultdict没有排序,下面的方法不会返回正确的值 是否有其他方法返回defaultdicts最近的可用密钥 from collections import defaultdict import numpy as np def_dict = defaultdict(list)

我使用defaultdicts存储值列表,其中
键是可以观察值的时段。
从所有感兴趣期间的列表中查找时,我希望在defaultdict中找到最近的期间(注意:并非所有期间都存储在defaultdict中)

但是,由于defaultdict没有排序,下面的方法不会返回正确的值

是否有其他方法返回defaultdicts最近的可用密钥

from collections import defaultdict
import numpy as np

def_dict = defaultdict(list)
# entries that will be stored in the defaultdict
reg_dict = {0: ["a", "b"], 2: ["c", "d"], 5: ["k", "h"], -3: ["i", "l"]}

# store items from regular dict in defaultdict 
for k, v in reg_dict.items():
    def_dict[k] = v

# Lookup periods
periods = [-1, 0, 1, 2, 3, 4, 5, 6, 7, 8]

for period in periods:

    # this approach does not return the right keys as defaultdicts are not sorted
    closest_key = np.abs(np.array(list(def_dict.keys())) - period).argmin()

    print("period: ", period, " - looked up key: ", closest_key)
这将返回以下内容:

period:  -1  - looked up key:  0
period:  0  - looked up key:  0
period:  1  - looked up key:  0
period:  2  - looked up key:  1
period:  3  - looked up key:  1
period:  4  - looked up key:  2
period:  5  - looked up key:  2
period:  6  - looked up key:  2
period:  7  - looked up key:  2
period:  8  - looked up key:  2

按照我的理解,您想要类似的输出吗

[0, 0, 0, 2, 2, 5, 5, 5, 5, 5]
对于上述情况,逻辑是

closest_key = [min(def_dict.keys(), key = lambda x: abs(x - p)) for p in periods]

为内置python函数指定可选的
参数在这种情况下很有用。

据我所知,您想要类似的输出吗

[0, 0, 0, 2, 2, 5, 5, 5, 5, 5]
对于上述情况,逻辑是

closest_key = [min(def_dict.keys(), key = lambda x: abs(x - p)) for p in periods]

为内置python函数指定可选的
key
参数在此类情况下非常有用。

我同意@septra的说法,即需要euqlidean距离,但这也可以通过numpy实现:

from collections import defaultdict
import numpy as np

def_dict = defaultdict(list)
# entries that will be stored in the defaultdict
reg_dict = {0: ["a", "b"], 2: ["c", "d"], 5: ["k", "h"], -3: ["i", "l"]}

# store items from regular dict in defaultdict 
for k, v in reg_dict.items():
    def_dict[k] = v

periods = [-1, 0, 1, 2, 3, 4, 5, 6, 7, 8]
a = list(def_dict.keys())
for period in periods:
    closest_key  = np.sqrt(np.power(np.add(a, -period),2)).argmin()
    # OR closest_key  = np.abs(np.add(a, -period)).argmin()

    print("period: ", period, " - looked up key: ", a[closest_key])

我同意@septra的说法,你需要euqlidean距离,但numpy也可以做到这一点:

from collections import defaultdict
import numpy as np

def_dict = defaultdict(list)
# entries that will be stored in the defaultdict
reg_dict = {0: ["a", "b"], 2: ["c", "d"], 5: ["k", "h"], -3: ["i", "l"]}

# store items from regular dict in defaultdict 
for k, v in reg_dict.items():
    def_dict[k] = v

periods = [-1, 0, 1, 2, 3, 4, 5, 6, 7, 8]
a = list(def_dict.keys())
for period in periods:
    closest_key  = np.sqrt(np.power(np.add(a, -period),2)).argmin()
    # OR closest_key  = np.abs(np.add(a, -period)).argmin()

    print("period: ", period, " - looked up key: ", a[closest_key])

使用
OrderedDict
和排序键,可以使用二进制搜索。 对于大量的键,查找将比当前的方法快得多

由于需要最接近的关键点,因此需要找到最右边的关键点低于x,最左边的关键点高于x。在为低于x的最右边的键找到索引
i
后,另一个候选键(最左边的键高于x)将位于索引
i+1

您需要确保这些索引仍在数组中

最后,您只需要计算从这两个值到x的距离


这是和的文档,带有一个
OrderedDict
和排序键,您可以使用二进制搜索。 对于大量的键,查找将比当前的方法快得多

由于需要最接近的关键点,因此需要找到最右边的关键点低于x,最左边的关键点高于x。在为低于x的最右边的键找到索引
i
后,另一个候选键(最左边的键高于x)将位于索引
i+1

您需要确保这些索引仍在数组中

最后,您只需要计算从这两个值到x的距离


这是和的文档

,正如Eric所说,要有效地执行此操作,您应该使用二进制搜索。然而,如果键的数量很小,简单的线性搜索可能就足够了。不需要使用defaultdict或OrderedDict,只需对键进行排序即可

import numpy as np

# entries
reg_dict = {0: ["a", "b"], 2: ["c", "d"], 5: ["k", "h"], -3: ["i", "l"]}

keys = np.array(sorted(reg_dict.keys()))
print('keys', keys)

# Lookup periods
periods = np.arange(-1, 9)

for period in periods:
    closest_key = keys[np.abs(keys - period).argmin()]
    print("period: ", period, " - looked up key: ", closest_key)
输出

keys [-3  0  2  5]
period:  -1  - looked up key:  0
period:  0  - looked up key:  0
period:  1  - looked up key:  0
period:  2  - looked up key:  2
period:  3  - looked up key:  2
period:  4  - looked up key:  5
period:  5  - looked up key:  5
period:  6  - looked up key:  5
period:  7  - looked up key:  5
period:  8  - looked up key:  5

正如Eric所说,要有效地执行此操作,您应该使用二进制搜索。然而,如果键的数量很小,简单的线性搜索可能就足够了。不需要使用defaultdict或OrderedDict,只需对键进行排序即可

import numpy as np

# entries
reg_dict = {0: ["a", "b"], 2: ["c", "d"], 5: ["k", "h"], -3: ["i", "l"]}

keys = np.array(sorted(reg_dict.keys()))
print('keys', keys)

# Lookup periods
periods = np.arange(-1, 9)

for period in periods:
    closest_key = keys[np.abs(keys - period).argmin()]
    print("period: ", period, " - looked up key: ", closest_key)
输出

keys [-3  0  2  5]
period:  -1  - looked up key:  0
period:  0  - looked up key:  0
period:  1  - looked up key:  0
period:  2  - looked up key:  2
period:  3  - looked up key:  2
period:  4  - looked up key:  5
period:  5  - looked up key:  5
period:  6  - looked up key:  5
period:  7  - looked up key:  5
period:  8  - looked up key:  5

1) 您实际上不需要一个
defaultdict
,一个
orderedict
就可以了,2您为什么不对键进行排序呢?您可以在帖子中显示预期的输出吗?argmin返回键,以便结果正确。如果需要值,请使用
min(最近的_键)
。1)您实际上不需要
defaultdict
,而
orderedict
可以工作,2为什么不对键进行排序?您可以在帖子中显示预期的输出吗?argmin返回键,以便结果正确。如果需要这些值,请使用
min(最近的_键)