检查一个给定的键是否已经存在于一个字典中,并增加它

给定一个字典,我怎样才能知道该字典中的给定键是否已经被设置为非无值?

即,我想要这样做:

my_dict = {} if (my_dict[key] != None): my_dict[key] = 1 else: my_dict[key] += 1 

也就是说,如果已经存在一个值,我想增加它的值,否则将其设置为1。

您正在寻找collections.defaultdict (适用于Python 2.5+)。 这个

 from collections import defaultdict my_dict = defaultdict(int) my_dict[key] += 1 

会做你想要的。

对于普通的Python dict ,如果没有给定键的值,那么在访问字典时不会得到None – 将会引发KeyError 。 所以,如果你想使用一个正规的dict ,而不是你使用的代码

 if key in my_dict: my_dict[key] += 1 else: my_dict[key] = 1 

我宁愿在一行代码中这样做。

 my_dict = {}

 my_dict [some_key] = my_dict.get(some_key,0)+ 1

字典有一个函数get,它带有两个参数 – 你想要的键,如果不存在,就有一个默认值。 我更喜欢这种方法defaultdict,因为你只想处理这种情况下,在这一行代码中不存在密钥,而不是到处都是。

你需要key in dictkey in dict

 if key in my_dict and not (my_dict[key] is None): # do something else: # do something else 

但是,您应该考虑使用defaultdict (如dFbuild议)。

我个人喜欢用setdefault()

 my_dict = {} my_dict.setdefault(some_key, 0) my_dict[some_key] += 1 

为了回答这个问题:“ 我怎样才能知道该字典中的给定索引是否已经设置为非无值 ”,我宁愿这样做:

 try: nonNone = my_dict[key] is not None except KeyError: nonNone = False 

这符合已经援引EAFP的概念(更容易请求宽恕,然后许可)。 它也避免了在字典中的重复密钥查找,因为它在key in my_dict and my_dict[key] is not None 。如果查找是昂贵的,那么有趣的是什么。

对于你提出的实际问题 ,即增加一个int,如果它存在,或者设置它为默认值,否则,我也build议

 my_dict[key] = my_dict.get(key, default) + 1 

就像安德鲁·威尔金森的回答一样。

如果在字典中存储可修改的对象,还有第三种解决scheme。 一个常见的例子就是一个multimap ,其中存储了您的密钥的元素列表。 在这种情况下,您可以使用:

 my_dict.setdefault(key, []).append(item) 

如果字典中不存在key的值,则setdefault方法将其设置为setdefault的第二个参数。 它的行为就像一个标准的my_dict [键],返回键的值(可能是新设置的值)。

正如你从许多答案中可以看到的,有几个解决scheme。 一个LBYL的实例(看你跳过)还没有被提到,has_key()方法:

 my_dict = {} def add (key): if my_dict.has_key(key): my_dict[key] += 1 else: my_dict[key] = 1 if __name__ == '__main__': add("foo") add("bar") add("foo") print my_dict 

同意cgoldberg。 我如何做到这一点是:

 try: dict[key] += 1 except KeyError: dict[key] = 1 

所以要么像上面那样做,要么像别人所说的那样使用默认的字典。 不要使用if语句。 这不是Pythonic。

你尝试这样做的方式被称为LBYL(在你跳跃之前),因为你正在检查条件,然后尝试增加你的价值。

另一种方法被称为EAFP(更容易请求宽恕,然后许可)。 在这种情况下,您只需尝试操作(增加值)。 如果失败,你会发现exception并将其值设置为1.这是一个稍微恶化的方法(IMO)。

http://mail.python.org/pipermail/python-list/2003-May/205182.html

有点晚了,但这应该工作。

 my_dict = {} my_dict[key] = my_dict[key] + 1 if key in my_dict else 1 

这是我最近提出的一个解决这个问题的方法。 它基于setdefault字典方法:

 my_dict = {} my_dict[key] = my_dict.setdefault(key, 0) + 1 

这不是直接回答这个问题,但对我来说,看起来你可能想要collections.Counter的function。

 from collections import Counter to_count = ["foo", "foo", "bar", "baz", "foo", "bar"] count = Counter(to_count) print(count) print("acts just like the desired dictionary:") print("bar occurs {} times".format(count["bar"])) print("any item that does not occur in the list is set to 0:") print("dog occurs {} times".format(count["dog"])) print("can iterate over items from most frequent to least:") for item, times in count.most_common(): print("{} occurs {} times".format(item, times)) 

这导致输出

 Counter({'foo': 3, 'bar': 2, 'baz': 1}) acts just like the desired dictionary: bar occurs 2 times any item that does not occur in the list is set to 0: dog occurs 0 times can iterate over items from most frequent to least: foo occurs 3 times bar occurs 2 times baz occurs 1 times 

我正在寻找它,没有发现它在networking上,然后尝试使用Try / Error的运气,发现它

 my_dict = {} if my_dict.__contains__(some_key): my_dict[some_key] += 1 else: my_dict[some_key] = 1