ある辞書を考えて、その辞書の中の与えられたキーがすでに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
sの場合、与えられたキーに値がなければ、辞書にアクセスするときにnotNone
を得ます - KeyError
が発生します。あなたのコードの代わりに通常のdict
を使いたいのであれば
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
ただし、(dFが推奨するように)defaultdict
を使用することをおそらく検討する必要があります。
「その辞書の特定のインデックスが既にNone以外の値に設定されているかどうかはどうすればわかりますか」という質問に答えるには、この:
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)
Keyの値が辞書に存在しない場合、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 __== '__main__':
add("foo")
add("bar")
add("foo")
print my_dict
あなたがそれをやろうとしている方法は、あなたがあなたの値を増加させようとする前に条件をチェックしているので、LBYLと呼ばれます。
もう1つのアプローチはEAFPと呼ばれます(許しを求めるよりも許しを求めるほうが簡単です)。その場合は、単に操作を試す(値を増やす)だけです。失敗した場合は、例外をキャッチして値を1に設定します。これはもう少しPythonicの方法です(IMO)。
http://mail.python.org/pipermail/python-list/2003-May/205182.html
これは直接質問に答えるものではありませんが、私には、 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
少し遅れますが、これでうまくいくはずです。
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
私はそれを探していました、それがウェブ上でそれを見つけなかったそしてそれからTry/Errorで私の運を試してみてそれを見つけました
my_dict = {}
if my_dict.__contains__(some_key):
my_dict[some_key] += 1
else:
my_dict[some_key] = 1