create - python dictionary append




تتكرر عبر القواميس باستخدام حلقات "for" (8)

تتكرر عبر القواميس باستخدام حلقات "for"

d = {'x': 1, 'y': 2, 'z': 3} 
for key in d:
    ...

كيف تدرك بايثون أنها تحتاج فقط إلى قراءة المفتاح من القاموس؟ هل مفتاح الكلمة الخاصة في بايثون؟ أم هو ببساطة متغير؟

انها ليست فقط من for الحلقات. الكلمة المهمة هنا هي "التكرار".

القاموس هو تخطيط مفاتيح القيم:

d = {'x': 1, 'y': 2, 'z': 3} 

في أي وقت نكرره ، نقوم بالتكرار فوق المفاتيح. الغرض من key اسم المتغير هو أن يكون وصفيًا - وهو مناسب تمامًا لهذا الغرض.

يحدث هذا في فهم القائمة:

>>> [k for k in d]
['x', 'y', 'z']

يحدث ذلك عندما نمر القاموس لقائمة (أو أي كائن نوع جمع آخر):

>>> list(d)
['x', 'y', 'z']

الطريقة التي تتكرر بها بيثون ، في سياق حيث تحتاج إليها ، تقوم باستدعاء طريقة __iter__ للكائن (في هذه الحالة القاموس) التي تقوم بإرجاع مكرر (في هذه الحالة ، كائن keyiterator):

>>> d.__iter__()
<dict_keyiterator object at 0x7fb1747bee08>

يجب ألا نستخدم هذه الأساليب الخاصة بأنفسنا ، بدلاً من ذلك ، استخدم وظيفة builtin الخاصة للاتصال بها ، iter :

>>> key_iterator = iter(d)
>>> key_iterator
<dict_keyiterator object at 0x7fb172fa9188>

__next__ طريقة __next__ - لكننا نسميها مع وظيفة مدمجة ، next :

>>> next(key_iterator)
'x'
>>> next(key_iterator)
'y'
>>> next(key_iterator)
'z'
>>> next(key_iterator)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration

عندما يتم استنفاذ مكرر ، فإنه يرفع StopIteration . هذه هي الطريقة التي تعرف بها بايثون الخروج من الحلقة ، أو فهم القائمة ، أو تعبير المولد ، أو أي سياق تكراري آخر. وبمجرد أن يرفع StopIteration فإنه سيعمل دائمًا على رفعه - إذا كنت تريد التكرار مرة أخرى ، فأنت بحاجة إلى وظيفة جديدة.

>>> list(key_iterator)
[]
>>> new_key_iterator = iter(d)
>>> list(new_key_iterator)
['x', 'y', 'z']

العودة إلى ديتس

رأينا dicts تتكرر في سياقات كثيرة. ما رأيناه هو أنه في أي وقت نقوم فيه بالتكرار من خلال أمر ، نحصل على المفاتيح. العودة إلى المثال الأصلي:

d = {'x': 1, 'y': 2, 'z': 3} 
for key in d:

إذا قمنا بتغيير اسم المتغير ، ما زلنا نحصل على المفاتيح. دعنا نحاول:

>>> for each_key in d:
...     print(each_key, '=>', d[each_key])
... 
x => 1
y => 2
z => 3

إذا أردنا التكرار أكثر من القيم ، نحتاج إلى استخدام طريقة .values ، أو كليهما معاً ،.

>>> list(d.values())
[1, 2, 3]
>>> list(d.items())
[('x', 1), ('y', 2), ('z', 3)]

في المثال المعطى ، سيكون أكثر كفاءة للتكرار على العناصر مثل هذا:

for a_key, corresponding_value in d.items():
    print(a_key, corresponding_value)

لكن للأغراض الأكاديمية ، مثال السؤال على ما يرام.

أشعر بالحيرة بعض الشيء بسبب الكود التالي:

d = {'x': 1, 'y': 2, 'z': 3} 
for key in d:
    print key, 'corresponds to', d[key]

ما لا أفهمه هو الجزء key . كيف تدرك بايثون أنها تحتاج فقط إلى قراءة المفتاح من القاموس؟ هل key الكلمة الخاصة في بايثون؟ أم هو ببساطة متغير؟


عندما تقوم بالتكرار من خلال القواميس باستخدام for .. in .. -syntax ، فإنه دائمًا يتكرر عبر المفاتيح (يمكن الوصول إلى القيم باستخدام dictionary[key] ).

للتكرار باستخدام أزواج key-value ، استخدم for k,v in s.iteritems() .


للتكرار أكثر من المفاتيح ، يكون أبطأ ولكن من الأفضل استخدام my_dict.keys() . إذا حاولت فعل شيء كالتالي:

for key in my_dict:
    my_dict[key+"-1"] = my_dict[key]-1

فإنه ينشئ خطأ وقت التشغيل لأنك تقوم بتغيير المفاتيح أثناء تشغيل البرنامج. إذا كنت for key in my_dict تمامًا لخفض الوقت ، فاستخدم for key in my_dict طريقة for key in my_dict ، ولكن تم تحذيرك ؛).


ليس هذا المفتاح هو كلمة خاصة ، ولكن هذه القواميس تنفذ بروتوكول المكرر. يمكنك القيام بذلك في صفك ، على سبيل المثال رؤية هذا السؤال لكيفية بناء برامج التكرار.

في حالة القواميس ، يتم تنفيذه على مستوى C. التفاصيل متوفرة في PEP 234 . على وجه الخصوص ، قسم بعنوان "قاموس المتعلمين":

  • تقوم القواميس بتطبيق فتحة tp_iter تقوم بإرجاع مكرر فعال يتكرر عبر مفاتيح القاموس. [...] وهذا يعني أنه يمكننا أن نكتب

    for k in dict: ...
    

    وهو ما يعادل ، ولكن أسرع بكثير من

    for k in dict.keys(): ...
    

    طالما لا يتم انتهاك تقييد التعديلات على القاموس (إما عن طريق حلقة أو من قبل موضوع آخر).

  • إضافة طرق إلى القواميس التي تعيد أنواعًا مختلفة من التكرارات صراحةً:

    for key in dict.iterkeys(): ...
    
    for value in dict.itervalues(): ...
    
    for key, value in dict.iteritems(): ...
    

    هذا يعني أن for x in dict هو اختصار for x in dict.iterkeys() .


يتكرر التكرار عبر أمر dict خلال مفاتيحه دون ترتيب معين ، كما يمكنك رؤيته هنا:

تعديل: ( لم يعد هذا هو الحال في Python3.6 ، ولكن لاحظ أنه ليس سلوكًا مضمونًا بعد)

>>> d = {'x': 1, 'y': 2, 'z': 3} 
>>> list(d)
['y', 'x', 'z']
>>> d.keys()
['y', 'x', 'z']

على سبيل المثال ، من الأفضل استخدام dict.items() :

>>> d.items()
[('y', 2), ('x', 1), ('z', 3)]

هذا يعطيك قائمة من tuples. عند التكرار فوقها مثل هذا ، يتم فك كل مجموعة tuple إلى k و v تلقائيًا:

for k,v in d.items():
    print(k, 'corresponds to', v)

استخدام k و v كأسماء المتغيرات عند التكرار على dict أمر شائع جدا إذا كان الجسم من حلقة ليست سوى عدد قليل من الخطوط. للحصول على حلقات أكثر تعقيدًا ، قد يكون من الأفضل استخدام المزيد من الأسماء الوصفية:

for letter, number in d.items():
    print(letter, 'corresponds to', number)

من الجيد أن تتعود على استخدام صيغ التنسيق:

for letter, number in d.items():
    print('{0} corresponds to {1}'.format(letter, number))

يمكنك استخدام هذا:

for key,val in d.items():
    print key, 'is the key for ', val

key هو ببساطة متغير.

ل Python2.X :

d = {'x': 1, 'y': 2, 'z': 3} 
for my_var in d:
    print my_var, 'corresponds to', d[my_var]

... أو أفضل ،

d = {'x': 1, 'y': 2, 'z': 3} 
for the_key, the_value in d.iteritems():
    print the_key, 'corresponds to', the_value

ل Python3.X :

d = {'x': 1, 'y': 2, 'z': 3} 
for the_key, the_value in d.items():
    print(the_key, 'corresponds to', the_value)

key هو مجرد اسم متغير.

for key in d:

سوف يتكرر ببساطة فوق المفاتيح في القاموس ، بدلاً من المفاتيح والقيم. للحلقة فوق كل من المفتاح والقيمة ، يمكنك استخدام ما يلي:

لبيثون 2.x:

for key, value in d.iteritems():

لبيثون 3.x:

for key, value in d.items():

لاختبار نفسك ، قم بتغيير key الكلمة إلى poop .

بالنسبة إلى Python 3.x ، تم استبدال iteritems() ببساطة items() ، التي ترجع عرضًا تشبه المجموعة التي تدعمها الدالة dict ، مثل iteritems() ولكن بشكل أفضل. هذا هو متاح أيضا في 2.7 كما viewitems() .

ستعمل items() العملية items() لكل من 2 و 3 ، ولكن في 2 ستعطي قائمة بأزواج (key, value) القاموس ، والتي لن تعكس التغييرات على الأمر الذي يحدث بعد استدعاء items() . إذا كنت تريد السلوك 2.x في 3.x ، يمكنك استدعاء list(d.items()) .





dictionary