从字典的列表中查找一个元素和 return 该键
Find an element from a list in a dictionary and return that key
如果我将 someDictionary
定义为
{'1': 33, '2': 44, '3': 55, '4': 10, '5': 66, '6': 60}
和someList
定义为
[51, 52, 53, 54, 55, 56]
如何在 someDictionary
中找到与 someList
中的元素相匹配的键?现在,我假设不会超过一场比赛。
我认为它会是这样的:
for k, v in someDictionary.items():
if v == someList:
myAnswer = k
鉴于上面的代码,myAnswer
将是 3
我需要做的第二部分是,如果 someList 不包含 someDictionary
中的元素,则找到 someDictionary
中大于(但最接近)最后一个元素的值一些列表 someList[-1]
在那种情况下,myAnswer 将是 6
第一部分,在列表中查找具有字典值的键列表。
someDictionary = {'1': 33, '2': 44, '3': 55, '4': 10, '5': 66, '6': 60}
someList = [51, 52, 53, 54, 55, 56]
res = [key for key, value in someDictionary.items() if value in someList]
第二部分,如果第一部分没有结果,找到最接近的较大值的键(继续):
if not res:
res = min ([(value, key) for key, value in someDictionary.items() if value > max(someList) ])[1]
myAnswer = ''
closest_to = someList[-1]
closest_diff = 0
for k in someDictionary:
if someDictionary[k] in someList:
myAnswer = k
break; # stop the loop when exact match found
diff = someDictionary[k] - closest_to
if diff > 0 and diff < closest_diff:
closest_diff = diff
myAnswer = k # this would save key of larger but closest number to last in someList
首先使用列表理解收集所有值在 lst
中的键,如果没有匹配则过滤值大于 lst[-1]
的键。在根据键值与 lst
中最后一项的差异的 abs 值对它们进行排序后,取 0
索引,最接近的项目。
dct = {'1': 33, '2': 44, '3': 55, '4': 10, '5': 66, '6': 60}
lst = [51, 52, 53, 54, 55, 56]
my_answer = [int(i) for i in dct if dct[i] in lst]
if my_answer:
print(*my_answer) # => 3
else:
close = [i for i in dct if int(dct[i]) > max(lst)]
closest = sorted(close, key=lambda x: abs(dct.get(x) - lst[-1]))[0]
print(closest) # => 6
How can I find the key in someDictionary
that matches an element in
someList
?
字典用于将键映射到值。在 O(1) 时间内不可能反向。但是您可以在 O(n) 时间内迭代,直到您可以将列表元素与字典值匹配。
您可以为此使用一个简单的 for
循环,迭代您的字典或列表。
d = {'1': 33, '2': 44, '3': 55, '4': 10, '5': 66, '6': 60}
L = [51, 52, 53, 54, 55, 56]
def find_key_dict(d, L):
L_set = set(L) # convert to set for O(1) lookup
for k, v in d.items():
if v in L_set:
return k
def find_key_list(d, L):
d_rev = {v: k for k, v in d.items()} # reverse dict for value -> key map
for i in L:
if i in d_rev:
return d_rev[i]
find_key_dict(d, L) # '3'
find_key_list(d, L) # '3'
也可以使用 next
将这些函数重写为 1 行生成器表达式,但这不一定更有效。
The second part I need to do is, if someList
does not contain an
element that is in someDictionary
, find the value in someDictionary
larger than (but closest to) the last element in someList
您可以使用 for... else...
构造和 min
:
编写类似的函数
def find_key_dict(d, L):
L_set = set(L) # convert to set for O(1) lookup
for k, v in d.items():
if v in L_set:
return k
else:
def min_func(x):
diff = x[1] - L[-1]
return diff <= 0, diff
return min(d.items(), key=min_func)[0]
find_key_dict(d, L) # '6'
对于第一个问题,您只是使用了错误的运算符来检查值是否在 someList
中
for k, v in someDictionary.items():
if v in someList:
myAnswer = k
关于第二个问题你可以这样扩展之前的代码
for k, v in someDictionary.items():
if v in someList:
myAnswer = k
break
else:
myAnswer = None
for k, v in someDictionary.items():
if v > someList[-1] and (myAnswer is None or v < someDictionary[myAnswer]):
myAnswer = k
听起来你想要一个 bidict
>>> from bidict import bidict # pip install bidict
>>> d = bidict({'1': 33, '2': 44, '3': 55, '4': 10, '5': 66, '6': 60})
>>> d['3'] 55
>>> d.inv[55] '3'
这允许在任一方向上进行 O(1) 次查找。现在,您可以遍历 someList
并有效地检查元素是否为 in d.inv
。
如果您的字典和列表很大,尤其是如果您有许多列表要针对同一个字典进行测试,则值得准备数据以便更快地执行。
__init__
中最差的操作是排序,O(n*log(n))。它允许我们使用 bisect
在 O(log(n)) 的最后一个案例中找到最接近的值。
from bisect import bisect
class FindInDict:
def __init__(self, someDictionary):
self.dict_by_values = {val: key for key, val in someDictionary.items()}
self.dict_values_set = set(sorted_values)
self.sorted_values = sorted(someDictionary.values())
def find(self, someList):
common = set(someList).intersection(self.dict_values_set)
if common:
key = self.dict_by_values[common.pop()]
else:
closest_value = self.sorted_values[bisect(self.sorted_values, someList[-1])]
key = self.dict_by_values[closest_value]
return key
someDictionary = {'1': 33, '2': 44, '3': 55, '4': 10, '5': 66, '6': 60}
finder = FindInDict(someDictionary)
finder.find([51, 52, 53, 54, 55, 56])
# 3
finder.find([51, 52, 53, 54, 56]) # no common value
# 6
这里有一些东西可以处理你的问题的两个部分,并且应该很容易修改以处理可能弹出的任何讨厌的 "edge-cases":
someDictionary = {'1': 33, '2': 44, '3': 55, '4': 10, '5': 66, '6': 60}
someList = [51, 52, 53, 54, 55, 56]
myAnswer = [key for key in someDictionary if someDictionary[key] in someList]
if not myAnswer:
diffs = {dict_key: dict_value-someList[-1]
for dict_key, dict_value in someDictionary.items()
if dict_value-someList[-1] > 0}
myAnswer = [min(diffs, key=diffs.get)] # Key of value with minimum
# (positive) difference
print(myAnswer)
如果我将 someDictionary
定义为
{'1': 33, '2': 44, '3': 55, '4': 10, '5': 66, '6': 60}
和someList
定义为
[51, 52, 53, 54, 55, 56]
如何在 someDictionary
中找到与 someList
中的元素相匹配的键?现在,我假设不会超过一场比赛。
我认为它会是这样的:
for k, v in someDictionary.items():
if v == someList:
myAnswer = k
鉴于上面的代码,myAnswer
将是 3
我需要做的第二部分是,如果 someList 不包含 someDictionary
中的元素,则找到 someDictionary
中大于(但最接近)最后一个元素的值一些列表 someList[-1]
在那种情况下,myAnswer 将是 6
第一部分,在列表中查找具有字典值的键列表。
someDictionary = {'1': 33, '2': 44, '3': 55, '4': 10, '5': 66, '6': 60}
someList = [51, 52, 53, 54, 55, 56]
res = [key for key, value in someDictionary.items() if value in someList]
第二部分,如果第一部分没有结果,找到最接近的较大值的键(继续):
if not res:
res = min ([(value, key) for key, value in someDictionary.items() if value > max(someList) ])[1]
myAnswer = ''
closest_to = someList[-1]
closest_diff = 0
for k in someDictionary:
if someDictionary[k] in someList:
myAnswer = k
break; # stop the loop when exact match found
diff = someDictionary[k] - closest_to
if diff > 0 and diff < closest_diff:
closest_diff = diff
myAnswer = k # this would save key of larger but closest number to last in someList
首先使用列表理解收集所有值在 lst
中的键,如果没有匹配则过滤值大于 lst[-1]
的键。在根据键值与 lst
中最后一项的差异的 abs 值对它们进行排序后,取 0
索引,最接近的项目。
dct = {'1': 33, '2': 44, '3': 55, '4': 10, '5': 66, '6': 60}
lst = [51, 52, 53, 54, 55, 56]
my_answer = [int(i) for i in dct if dct[i] in lst]
if my_answer:
print(*my_answer) # => 3
else:
close = [i for i in dct if int(dct[i]) > max(lst)]
closest = sorted(close, key=lambda x: abs(dct.get(x) - lst[-1]))[0]
print(closest) # => 6
How can I find the key in
someDictionary
that matches an element insomeList
?
字典用于将键映射到值。在 O(1) 时间内不可能反向。但是您可以在 O(n) 时间内迭代,直到您可以将列表元素与字典值匹配。
您可以为此使用一个简单的 for
循环,迭代您的字典或列表。
d = {'1': 33, '2': 44, '3': 55, '4': 10, '5': 66, '6': 60}
L = [51, 52, 53, 54, 55, 56]
def find_key_dict(d, L):
L_set = set(L) # convert to set for O(1) lookup
for k, v in d.items():
if v in L_set:
return k
def find_key_list(d, L):
d_rev = {v: k for k, v in d.items()} # reverse dict for value -> key map
for i in L:
if i in d_rev:
return d_rev[i]
find_key_dict(d, L) # '3'
find_key_list(d, L) # '3'
也可以使用 next
将这些函数重写为 1 行生成器表达式,但这不一定更有效。
The second part I need to do is, if
someList
does not contain an element that is insomeDictionary
, find the value insomeDictionary
larger than (but closest to) the last element insomeList
您可以使用 for... else...
构造和 min
:
def find_key_dict(d, L):
L_set = set(L) # convert to set for O(1) lookup
for k, v in d.items():
if v in L_set:
return k
else:
def min_func(x):
diff = x[1] - L[-1]
return diff <= 0, diff
return min(d.items(), key=min_func)[0]
find_key_dict(d, L) # '6'
对于第一个问题,您只是使用了错误的运算符来检查值是否在 someList
for k, v in someDictionary.items():
if v in someList:
myAnswer = k
关于第二个问题你可以这样扩展之前的代码
for k, v in someDictionary.items():
if v in someList:
myAnswer = k
break
else:
myAnswer = None
for k, v in someDictionary.items():
if v > someList[-1] and (myAnswer is None or v < someDictionary[myAnswer]):
myAnswer = k
听起来你想要一个 bidict
>>> from bidict import bidict # pip install bidict
>>> d = bidict({'1': 33, '2': 44, '3': 55, '4': 10, '5': 66, '6': 60})
>>> d['3'] 55
>>> d.inv[55] '3'
这允许在任一方向上进行 O(1) 次查找。现在,您可以遍历 someList
并有效地检查元素是否为 in d.inv
。
如果您的字典和列表很大,尤其是如果您有许多列表要针对同一个字典进行测试,则值得准备数据以便更快地执行。
__init__
中最差的操作是排序,O(n*log(n))。它允许我们使用 bisect
在 O(log(n)) 的最后一个案例中找到最接近的值。
from bisect import bisect
class FindInDict:
def __init__(self, someDictionary):
self.dict_by_values = {val: key for key, val in someDictionary.items()}
self.dict_values_set = set(sorted_values)
self.sorted_values = sorted(someDictionary.values())
def find(self, someList):
common = set(someList).intersection(self.dict_values_set)
if common:
key = self.dict_by_values[common.pop()]
else:
closest_value = self.sorted_values[bisect(self.sorted_values, someList[-1])]
key = self.dict_by_values[closest_value]
return key
someDictionary = {'1': 33, '2': 44, '3': 55, '4': 10, '5': 66, '6': 60}
finder = FindInDict(someDictionary)
finder.find([51, 52, 53, 54, 55, 56])
# 3
finder.find([51, 52, 53, 54, 56]) # no common value
# 6
这里有一些东西可以处理你的问题的两个部分,并且应该很容易修改以处理可能弹出的任何讨厌的 "edge-cases":
someDictionary = {'1': 33, '2': 44, '3': 55, '4': 10, '5': 66, '6': 60}
someList = [51, 52, 53, 54, 55, 56]
myAnswer = [key for key in someDictionary if someDictionary[key] in someList]
if not myAnswer:
diffs = {dict_key: dict_value-someList[-1]
for dict_key, dict_value in someDictionary.items()
if dict_value-someList[-1] > 0}
myAnswer = [min(diffs, key=diffs.get)] # Key of value with minimum
# (positive) difference
print(myAnswer)