Проверьте, существует ли данный ключ в словаре, и увеличьте его

StackOverflow https://stackoverflow.com/questions/473099

  •  19-08-2019
  •  | 
  •  

Вопрос

Учитывая словарь, как я могу узнать, задан ли для данного ключа в этом словаре значение, отличное от None?

То есть, я хочу сделать это:

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 при доступе к dict - будет возбуждено KeyError. Так что если вы хотите использовать обычный <=>, вместо вашего кода вы бы использовали

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, которая принимает два параметра - нужный вам ключ и значение по умолчанию, если оно не существует. Я предпочитаю, чтобы этот метод использовался по умолчанию, поскольку вы хотите обрабатывать только тот случай, когда ключ не существует в этой строке кода, а не везде.

Мне лично нравится использовать setdefault()

my_dict = {}

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

Для этого вам понадобится key in dict идиома.

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

Однако вам, вероятно, следует подумать об использовании defaultdict (в соответствии с предложением dF).

Чтобы ответить на вопрос " как я могу узнать, было ли заданному индексу в этом dict задано ненулевое значение " я бы предпочел это:

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

как в ответе Эндрю Уилкинсона.

Существует третье решение, если вы храните изменяемые объекты в своем словаре. Типичным примером этого является мультикарта , где вы храните список элементов для ваших ключей. В этом случае вы можете использовать:

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

Если значение для ключа не существует в словаре, метод setdefault установит для него второй параметр setdefault. Он ведет себя так же, как стандартный my_dict [ключ], возвращая значение для ключа (которое может быть вновь установленным значением).

Согласился с cgoldberg. Как я это делаю:

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

Так что либо делайте это, как указано выше, либо используйте dict по умолчанию, как предлагали другие. Не используйте операторы if. Это не Pythonic.

Как видно из множества ответов, есть несколько решений. Один экземпляр 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

Способ, которым вы пытаетесь это сделать, называется LBYL (посмотрите, прежде чем прыгнуть), поскольку вы проверяете условия перед тем, как пытаться увеличить свое значение.

Другой подход называется EAFP (проще попросить прощения, чем разрешения). В этом случае вы просто попытаетесь выполнить операцию (увеличить значение). Если это не удается, вы перехватываете исключение и устанавливаете значение 1. Это немного более Pythonic способ сделать это (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

Это не дает прямого ответа на вопрос, но для меня это выглядит так, как будто вам может потребоваться функциональность collection.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

Вот одна строчка, которую я недавно придумал для решения этой проблемы. Он основан на setdefault методе словаря:

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

Я искал его, не нашел его в Интернете, затем попытал счастья с помощью Try / Error и нашел его

my_dict = {}

if my_dict.__contains__(some_key):
  my_dict[some_key] += 1
else:
  my_dict[some_key] = 1
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top