我做了一个函数,它将在字典中查找年龄并显示匹配的名字:
dictionary = {'george' : 16, 'amber' : 19}
search_age = raw_input("Provide age")
for age in dictionary.values():
if age == search_age:
name = dictionary[age]
print name
我知道如何比较和查找年龄,只是不知道如何显示这个人的名字。此外,由于第5行,我得到了一个KeyError。我知道这是不正确的,但我不知道如何让它向后搜索。
如果你想要名字和年龄,你应该使用.items(),它会给你key (key, value)元组:
for name, age in mydict.items():
if age == search_age:
print name
您可以在for循环中将元组解包为两个单独的变量,然后匹配年龄。
如果你通常要根据年龄查找,而且没有两个人的年龄相同,你还应该考虑颠倒字典:
{16: 'george', 19: 'amber'}
所以你可以通过这样做来查找这个名字
mydict[search_age]
我一直称它为mydict而不是list,因为list是内置类型的名称,你不应该将这个名称用于其他任何类型。
你甚至可以在一行中得到给定年龄的所有人的列表:
[name for name, age in mydict.items() if age == search_age]
或者如果每个年龄只有一个人:
next((name for name, age in mydict.items() if age == search_age), None)
如果没有这个年龄的人,就会给你None。
最后,如果字典很长并且你使用的是Python 2,你应该考虑使用.iteritems()而不是像Cat Plus Plus在他的回答中所做的那样使用.items(),因为它不需要复制列表。
这是一个真正的“可逆字典”,基于Adam Acosta的解决方案,但强制val-to-key调用是唯一的,容易从值返回键:
from collections import UserDict
class ReversibleDict(UserDict):
def __init__(self, enforce_unique=True, *args, **kwargs):
super().__init__(*args, **kwargs)
self.val_to_keys = {}
self.check_val = self.check_unique if enforce_unique else lambda x: x
def __setitem__(self, key, value):
self.check_val(value)
super().__setitem__(key, value)
self.val_to_keys[value] = key
def __call__(self, value):
return self.val_to_keys[value]
def check_unique(self, value):
assert value not in self.val_to_keys, f"Non unique value '{value}'"
return value
如果你想强制字典值的唯一性,确保set enforce_unique=True。从值中获取键只需做rev_dict(value),从键中调用值只需像往常一样做dict['key'],这里是一个用法示例:
rev_dict = ReversibleDict(enforce_unique=True)
rev_dict["a"] = 1
rev_dict["b"] = 2
rev_dict["c"] = 3
print("full dictinoary is: ", rev_dict)
print("value for key 'b' is: ", rev_dict["b"])
print("key for value '2' is: ", rev_dict(2))
print("tring to set another key with the same value results in error: ")
rev_dict["d"] = 1
我意识到已经有很长一段时间了,最初的提问者可能不再需要答案,但如果您实际上可以控制这段代码,那么这些答案都不是好的答案。您只是使用了错误的数据结构。这是双向字典用例的完美说明:
>>> from collections import defaultdict, UserDict
>>> class TwoWayDict(UserDict):
... def __init__(self, *args, **kwargs):
... super().__init__(*args, **kwargs)
... self.val_to_keys = defaultdict(list)
... def __setitem__(self, key, value):
... super().__setitem__(key, value)
... self.val_to_keys[value].append(key)
... def get_keys_for_val(self, value):
... return self.val_to_keys[value]
...
>>> d = TwoWayDict()
>>> d['a'] = 1
>>> d['b'] = 1
>>> d.get_keys_for_val(1)
['a', 'b']
为插入增加了极小的开销,但您保持了恒定的查找时间,除了现在是双向查找。不需要在每次需要时从头构造反向映射。只要在你需要的时候存储它并访问它。
此外,这些答案中有许多甚至是不正确的,因为很明显,许多人可能具有相同的年龄,但他们只返回第一个匹配的键,而不是所有的键。