Check if a given key already exists in a dictionary and increment it
给定一个字典,我如何才能确定该字典中的给定键是否已设置为非无值?
也就是说,我想这样做:
1 2 3 4 5 6 | my_dict = {} if (my_dict[key] != None): my_dict[key] = 1 else: my_dict[key] += 1 |
也就是说,如果已经有一个值,我想增加这个值,否则设置为1。
您正在查找
1 2 3 4 | from collections import defaultdict my_dict = defaultdict(int) my_dict[key] += 1 |
会做你想做的。
对于常规的python
1 2 3 4 | if key in my_dict: my_dict[key] += 1 else: my_dict[key] = 1 |
我更喜欢用一行代码来完成这项工作。
1 2 3 | my_dict = {} my_dict[some_key] = my_dict.get(some_key, 0) + 1 |
字典有一个函数get,它接受两个参数——您想要的键,如果不存在的话还有一个默认值。我更喜欢这个方法而不是默认dict,因为您只想处理键不在这一行代码中的情况,而不是在任何地方。
我个人喜欢使用
1 2 3 4 | my_dict = {} my_dict.setdefault(some_key, 0) my_dict[some_key] += 1 |
为此,您需要使用
1 2 3 4 | if key in my_dict and not (my_dict[key] is None): # do something else: # do something else |
但是,您可能应该考虑使用
要回答"如何确定该dict中的给定索引是否已设置为非无值"的问题,我希望这样做:
1 2 3 4 | try: nonNone = my_dict[key] is not None except KeyError: nonNone = False |
这符合已经被调用的EAFP概念(先请求原谅,后请求许可)。它还避免了字典中的重复键查找,就像在
对于您提出的实际问题,例如,如果存在int,则递增它,或者将其设置为默认值,否则,我还建议
1 | my_dict[key] = my_dict.get(key, default) + 1 |
就像安德鲁·威尔金森的回答一样。
如果要在字典中存储可修改对象,则还有第三种解决方案。这方面的一个常见示例是多映射,在多映射中存储键的元素列表。在这种情况下,您可以使用:
1 | my_dict.setdefault(key, []).append(item) |
如果字典中不存在键的值,setdefault方法会将其设置为setdefault的第二个参数。它的行为就像标准的my-dict[键],返回键的值(可能是新设置的值)。
同意CGoldberg。我是怎么做到的:
1 2 3 4 | try: dict[key] += 1 except KeyError: dict[key] = 1 |
所以要么像上面所说的那样做,要么像其他人建议的那样使用默认的dict。不要使用if语句。那不是Python。
正如您从许多答案中看到的,有几个解决方案。还没有提到lbyl的一个实例(在跳跃前查看),has_key()方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 | 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 |
您尝试这样做的方式称为lbyl(在跳跃之前查看),因为您在尝试增加值之前检查条件。
另一种方法称为EAFP(先请求原谅,后请求许可)。在这种情况下,您只需尝试该操作(增加值)。如果失败,则捕获异常并将值设置为1。这是一个稍微多一些的Python式的方法来做它(IMO)。
http://mail.python.org/pipermail/python-list/2003-may/205182.html
这不是直接回答问题,但在我看来,您可能需要collections.counter的功能。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | 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)) |
这将导致输出
1 2 3 4 5 6 7 8 9 | 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 |
有点晚了,但这应该管用。
1 2 | my_dict = {} my_dict[key] = my_dict[key] + 1 if key in my_dict else 1 |
这是我最近为解决这个问题而提出的一条建议。它基于setdefault dictionary方法:
1 2 | my_dict = {} my_dict[key] = my_dict.setdefault(key, 0) + 1 |
我在找它,没有在网上找到它,然后用try/error试试运气,找到了它。
1 2 3 4 5 6 | my_dict = {} if my_dict.__contains__(some_key): my_dict[some_key] += 1 else: my_dict[some_key] = 1 |