检查给定键是否已存在于字典中并递增

问题:检查给定键是否已存在于字典中并递增

给定字典,我如何找出该字典中的给定键是否已设置为非值?

即,我想这样做:

my_dict = {}

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

即,如果要已有一个,我想增加该值,否则,请将该值设置为1。

Given a dictionary, how can I find out if a given key in that dictionary has already been set to a non-None value?

I.e., I want to do this:

my_dict = {}

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

I.e., I want to increment the value if there’s already one there, or set it to 1 otherwise.


回答 0

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

from collections import defaultdict

my_dict = defaultdict(int)
my_dict[key] += 1

会做你想要的。

对于常规Python而言dict,如果给定键没有值,则访问dict时不会获得结果NoneKeyError将会引发a。因此,如果您想使用Regular dict而不是代码,则可以使用

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

You are looking for collections.defaultdict (available for Python 2.5+). This

from collections import defaultdict

my_dict = defaultdict(int)
my_dict[key] += 1

will do what you want.

For regular Python dicts, if there is no value for a given key, you will not get None when accessing the dict — a KeyError will be raised. So if you want to use a regular dict, instead of your code you would use

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

回答 1

我更喜欢用一行代码来做到这一点。

my_dict = {}

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

字典具有一个函数get,该函数带有两个参数-所需的键和默认值(如果不存在)。我更喜欢这种方法作为defaultdict,因为您只想处理在这一行代码中不存在该键,而不是在所有地方都不存在该键的情况。

I prefer to do this in one line of code.

my_dict = {}

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

Dictionaries have a function, get, which takes two parameters – the key you want, and a default value if it doesn’t exist. I prefer this method to defaultdict as you only want to handle the case where the key doesn’t exist in this one line of code, not everywhere.


回答 2

我个人喜欢使用 setdefault()

my_dict = {}

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

I personally like using setdefault()

my_dict = {}

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

回答 3

您需要这样的key in dict成语。

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

但是,您可能应该考虑使用defaultdict(按dF建议)。

You need the key in dict idiom for that.

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

However, you should probably consider using defaultdict (as dF suggested).


回答 4

要回答“ 我如何找出该字典中的给定索引是否已设置为非值 ”的问题,我希望这样做:

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(如果存在),或者将其设置为默认值,我也建议

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

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

如果要在字典中存储可修改的对象,则有第三种解决方案。一个常见的示例是multimap,您可以在其中存储键的元素列表。在这种情况下,您可以使用:

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

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

To answer the question “how can I find out if a given index in that dict has already been set to a non-None value“, I would prefer this:

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

This conforms to the already invoked concept of EAFP (easier to ask forgiveness then permission). It also avoids the duplicate key lookup in the dictionary as it would in key in my_dict and my_dict[key] is not None what is interesting if lookup is expensive.

For the actual problem that you have posed, i.e. incrementing an int if it exists, or setting it to a default value otherwise, I also recommend the

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

as in the answer of Andrew Wilkinson.

There is a third solution if you are storing modifyable objects in your dictionary. A common example for this is a multimap, where you store a list of elements for your keys. In that case, you can use:

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

If a value for key does not exist in the dictionary, the setdefault method will set it to the second parameter of setdefault. It behaves just like a standard my_dict[key], returning the value for the key (which may be the newly set value).


回答 5

同意cgoldberg。我是怎么做的:

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

因此,要么如上所述,要么使用其他人建议的默认字典。不要使用if语句。那不是Pythonic。

Agreed with cgoldberg. How I do it is:

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

So either do it as above, or use a default dict as others have suggested. Don’t use if statements. That’s not Pythonic.


回答 6

从许多答案中可以看出,有几种解决方案。has_key()方法尚未提及LBYL的一个实例(三步前进)。

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

As you can see from the many answers, there are several solutions. One instance of LBYL (look before you leap) has not been mentioned yet, the has_key() method:

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

回答 7

您尝试执行此操作的方法称为LBYL(跳前先查看),因为您在尝试尝试增加值之前正在检查条件。

另一种方法称为EAFP(更容易先请求宽恕然后再允许)。在这种情况下,您只需尝试操作(增加值)。如果失败,则捕获该异常并将其值设置为1。这是使用Python的方式稍多一些(IMO)。

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

The way you are trying to do it is called LBYL (look before you leap), since you are checking conditions before trying to increment your value.

The other approach is called EAFP (easier to ask forgiveness then permission). In that case, you would just try the operation (increment the value). If it fails, you catch the exception and set the value to 1. This is a slightly more Pythonic way to do it (IMO).

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


回答 8

有点晚了,但这应该可行。

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

A bit late but this should work.

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

回答 9

这不是直接回答问题,但对我来说,您似乎可能需要collections.Counter的功能。

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

This isn’t directly answering the question, but to me, it looks like you might want the functionality of collections.Counter.

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))

This results in the output

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

回答 10

这是我最近为解决此问题而想出的一种方法。它基于setdefault词典方法:

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

Here’s one-liner that I came up with recently for solving this problem. It’s based on the setdefault dictionary method:

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

回答 11

我一直在寻找它,没有在网上找到它,然后尝试使用Try / Error运气并找到了它

my_dict = {}

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

I was looking for it, didn’t found it on web then tried my luck with Try/Error and found it

my_dict = {}

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