الثعبان: والتكرار على قائمة غير فارغة مع عدم وجود لو-بند تأتي فارغة. لماذا ا؟
-
22-08-2019 - |
سؤال
وكيف يمكن مكرر على تسلسل غير فارغة، مع عدم ترشيح وليس التجميع (sum()
، الخ)، وتسفر عن شيء؟
والنظر في مثال بسيط:
sequence = ['a', 'b', 'c']
list((el, ord(el)) for el in sequence)
وهذا ينتج [('a', 97), ('b', 98), ('c', 99)]
كما هو متوقع.
والآن، مجرد مبادلة ord(el)
من أجل التعبير الذي يأخذ القيمة الأولى من بعض مولد باستخدام (...).next()
- يغفر المثال مفتعلة:
def odd_integers_up_to_length(str):
return (x for x in xrange(len(str)) if x%2==1)
list((el, odd_integers_up_to_length(el).next()) for el in sequence)
وهذا ينتج []
. نعم، قائمة فارغة. لا الصفوف ('a',
stuff)
. لا شيء.
ولكن نحن لا تصفية أو تجميع أو الحد. تعبير مولد على n
كائنات دون تصفية أو تجميع يجب أن تسفر عن الأجسام n
، أليس كذلك؟ ما الذي يحدث؟
المحلول
وسوف odd_integers_up_to_length(el).next()
رفع StopIteration، والتي لم يتم اكتشاف هناك، ولكن يتم اكتشاف للتعبير عن مولد في داخلها، ووقف من دون الرضوخ أي شيء.
ونظرة على التكرار الأول، عندما تكون القيمة "أ":
>>> odd_integers_up_to_length('a').next()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
نصائح أخرى
وما يحدث هو أن الدعوة next()
تثير استثناء StopIteration
، الذي فقاعات فوق كومة إلى التعبير مولد الخارجي وتوقف <م> أن م> التكرار.
وA StopIteration
هي الطريقة الطبيعية للمكرر للإشارة إلى أن يتم ذلك. عموما نحن لا نرى ذلك، لأن عموما الدعوة next()
يحدث داخل التركيبة الذي يستهلك مكرر، على سبيل المثال for x in iterator
أو sum(iterator)
. ولكن عندما ندعو next()
مباشرة، ونحن هم المسؤولة عن اصطياد StopIteration
. عدم القيام بذلك الينابيع تسرب في التجريد، الأمر الذي يؤدي إلى سلوك غير متوقع هنا في التكرار الخارجي.
والدرس، وأفترض: كن حذرا حول المكالمات مباشرة إلى next()
وشارع هو الكلمة المحجوزة، يجب أن اسم متغير بشكل مختلف
وكنت أيضا لتقديم المشورة حول القادمة
>>> seq=['a','b','c']
>>> list((el,4) for el in seq)
[('a',4), ('b',4), ('c',4)]
وحتى انها ليست list
مما يتيح لك المتاعب هنا ...