معرفة ما إذا كان المفتاح موجود مسبقا في القاموس وزيادة فإنه

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 (متوفر لبيثون 2.5 +). هذا

from collections import defaultdict

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

وسوف تفعل ما تريد.

لdicts بيثون العادية، إذا لم يكن هناك قيمة للحصول على مفتاح معين، سوف <م> لا الحصول على None عند الوصول إلى ديكت لك - سيتم أثار KeyError. حتى إذا كنت ترغب في استخدام dict العادية، بدلا من التعليمات البرمجية التي ستستخدمها

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

وقواميس لها وظيفة، والحصول، والتي تأخذ معلمتين - المفتاح الذي تريد، وقيمة افتراضية إذا لم يكن موجودا. أنا أفضل هذا الأسلوب ل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).

لالإجابة على السؤال " كيف يمكنني معرفة ما إذا كان قد تم بالفعل وضع مؤشر معين في هذا ديكت إلى قيمة غير لا شيء "، وأود أن تفضل هذا:

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

وهذا يتفق مع مفهوم الاستشهاد بالفعل من EAFP (أسهل ليستغفر ثم إذن). كما أنه يتجنب لبحث المفاتيح المكررة في القاموس لانها ستكون في key in my_dict and my_dict[key] is not None ما هي مثيرة للاهتمام إذا بحث مكلفة.

لو<م> المشكلة الفعلية أن كنت قد طرحت، أي تزايد عدد صحيح إذا كان موجودا، أو تعيين إلى قيمة افتراضية غير ذلك، وأوصى أيضا

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

وكما هو الحال في إجابة لاندرو ويلكنسون.

وهناك حل ثالث إذا كنت تخزين كائنات modifyable في قاموسك. ومن الأمثلة الشائعة لهذا هو multimap ، حيث يمكنك تخزين قائمة العناصر لمفاتيحك. في هذه الحالة، يمكنك استخدام:

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

إذا لم توجد قيمة المفتاح في القاموس، فإن طريقة setdefault تعيينها إلى المعلمة الثانية من setdefault. انها تتصرف تماما مثل my_dict معيار [مفتاح]، إرجاع القيمة للمفتاح (والتي قد تكون القيمة المعينة حديثا).

ومتفق عليها مع cgoldberg. كيف أفعل ذلك هو:

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

وهكذا إما أن تفعل ذلك على النحو الوارد أعلاه، أو استخدام ديكت الافتراضي كما اقترح البعض. لا تستخدم إذا كانت تصريحات. هذا ليس 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

وهذه ليست إجابة مباشرة على السؤال، ولكن بالنسبة لي، يبدو أنك قد ترغب وظائف <لأ href = "https://docs.python.org/3/library/collections.html#collections. مكافحة "يختلط =" noreferrer "> 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

وكنت أبحث عنه، لم لم يتم العثور على الويب ثم حاول لي الحظ مع محاولة / خطأ، ووجدت أنها

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