ディクショナリが与えられた場合、そのディクショナリの特定のキーがすでにNon-None値に設定されているかどうかをどのように確認できますか?
つまり、私はこれをしたいです:
my_dict = {}
if (my_dict[key] != None):
my_dict[key] = 1
else:
my_dict[key] += 1
つまり、すでに値がある場合は値を増やし、それ以外の場合は1に設定します。
ディクショナリが与えられた場合、そのディクショナリの特定のキーがすでにNon-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にアクセスしても取得されません-a KeyError
が発生します。したがって、通常のを使用したい場合dict
は、コードの代わりに
if key in my_dict:
my_dict[key] += 1
else:
my_dict[key] = 1
dict
のsの場合、実行できますmy_dict[key] = my_dict.get(key, 0) + 1
。
私はこれを1行のコードで行うことを好みます。
my_dict = {} my_dict [some_key] = my_dict.get(some_key、0)+ 1
辞書にはgetという関数があり、2つのパラメーター(必要なキーと、存在しない場合のデフォルト値)を取ります。このメソッドはdefaultdictよりも優先されます。キーがこのコードの1行に存在しない場合にのみ処理する必要があるためです。
key in dict
そのためのイディオムが必要です。
if key in my_dict and not (my_dict[key] is None):
# do something
else:
# do something else
ただし、おそらく使用を検討する必要がありますdefaultdict
(dFが提案したとおり)。
my_dict[key] is not None
より明確な(少なくとも
if key in my_dict and my_dict[key]:
「その辞書の特定のインデックスがすでにNon-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
アンドリュー・ウィルキンソンの答えのように。
変更可能なオブジェクトをディクショナリに格納する場合、3番目の解決策があります。この一般的な例は、キーの要素のリストを格納するmultimapです。その場合、以下を使用できます。
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ではありません。
+=2
場合は-=1
どうなりますか?両方の行を変更することを忘れないでください。今では些細なことのように思えるかもしれませんが、それらは、あなたに噛み付くように戻ってくることができる、一種の愚かな小さな「小さな」バグです。
多くの答えからわかるように、いくつかの解決策があります。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
defaultdict(int)
、いくつかの追加機能と同様に機能するため、整数のみを処理する場合に完全に機能しますが、関連する動作は表示されません。
これが、この問題を解決するために最近思いついたワンライナーです。これは、setdefault辞書メソッドに基づいています。
my_dict = {}
my_dict[key] = my_dict.setdefault(key, 0) + 1
私はそれを探していました、それをウェブ上で見つけられなかったそしてそれからトライ/エラーで私の運を試し、それを見つけました
my_dict = {}
if my_dict.__contains__(some_key):
my_dict[some_key] += 1
else:
my_dict[some_key] = 1
__contains__
コードでは使用しないでください。ところで。__contains__
を使用するのと同じis
です。
my_dict.__contains__(some_key)
はと同等でありsome_key in my_dict
、in
オペレーターにとっては過負荷ではありませんis