指定されたキーが既に辞書に存在するかどうかを確認し、それをインクリメントします

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

  •  19-08-2019
  •  | 
  •  

質問

辞書がある場合、その辞書の特定のキーがすでに非なしの値に設定されているかどうかを確認するにはどうすればよいですか?

つまり、これをしたい:

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の場合、指定されたキーに値がない場合、dictにアクセスするときにNoneを取得しない -KeyErrorが発生します。したがって、コードの代わりに通常の<=>を使用する場合は、

を使用します
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という関数があります。この関数は、必要なキーと、存在しない場合の既定値の2つのパラメーターを受け取ります。キーがすべてのコードではなく、この1行のコードに存在しない場合のみを処理するため、このメソッドをdefaultdictよりも好みます。

個人的には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の推奨どおり)。

質問に答えるには、<!> quot; その辞書の特定のインデックスがすでに非None値に設定されているかどうかを調べる方法 <!> quot;これ:

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の回答のように。

辞書に変更可能なオブジェクトを保存する場合、3番目の解決策があります。これの一般的な例は、マルチマップで、キーの要素のリストを保存します。その場合、次を使用できます。

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

キーの値がディクショナリに存在しない場合、setdefaultメソッドはその値をsetdefaultの2番目のパラメーターに設定します。標準のmy_dict [key]と同じように動作し、キーの値(新しく設定された値の場合もあります)を返します。

cgoldbergと合意しました。方法:

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

したがって、上記のように行うか、他の人が示唆しているデフォルトの辞書を使用します。 ifステートメントは使用しないでください。 Pythonicではありません。

多くの回答からわかるように、いくつかの解決策があります。 LBYL(飛ぶ前に見える)の1つのインスタンスはまだ言及されていません。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(跳躍する前に見える)と呼ばれます。

もう1つのアプローチはEAFPと呼ばれます(許しを求めてから許可を求める方が簡単です)。その場合は、操作を試すだけです(値を増やします)。失敗した場合は、例外をキャッチし、値を1に設定します。これは、Pythonを使用した若干の方法(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

これは質問に直接答えているわけではありませんが、私には 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

この問題を解決するために最近思いついたワンライナーです。 setdefault 辞書メソッドに基づいています:

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

探していましたが、Webで見つけられなかったので、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