معظم Pythonic الطريق أي ما يعادل:في حين أن ((x = المقبلة()) != END)

StackOverflow https://stackoverflow.com/questions/28559

  •  09-06-2019
  •  | 
  •  

سؤال

ما هي أفضل لغة بايثون لهذا C بناء?

while ((x = next()) != END) {
    ....
}

ليس لدي القدرة على إعادة رمز القادمة().

تحديث:والجواب من يبدو أن:

for x in iter(next, END):
    ....
هل كانت مفيدة؟

المحلول

الجواب القصير:ليس هناك طريقة للقيام مضمنة تعيين متغير في حين حلقة في بيثون.معنى هذا أنا لا أقول:

while x=next():
    // do something here!

لأن هذا غير ممكن ، هناك عدد من "واصطلاحا الصحيح" طرق للقيام بذلك:

while 1:
    x = next()
    if x != END:
        // Blah
    else:
        break

ومن الواضح أن هذا هو نوع من القبيح.يمكنك أيضا استخدام أحد "مكرر" النهج المذكورة أعلاه, ولكن, مرة أخرى, التي قد لا تكون مثالية.أخيرا, يمكنك استخدام "بيتا جيب" نهج في الواقع أنا فقط وجدت أثناء البحث في قوقل:

class Pita( object ):
    __slots__ = ('pocket',)
    marker = object()
    def __init__(self, v=marker):
        if v is not self.marker:
            self.pocket = v
    def __call__(self, v=marker):
        if v is not self.marker:
            self.pocket = v
        return self.pocket

الآن يمكنك أن تفعل:

p = Pita()
while p( next() ) != END:
    // do stuff with p.pocket!

شكرا على هذا السؤال ؛ التعلم عن __call__ المصطلح كان حقا بارد!:)

تحرير:أود أن منح الائتمان حيث يرجع.في 'جيب بيتا' لغة وجد هنا

نصائح أخرى

@مارك هاريسون الجواب:

for x in iter(next_, END):
    ....

وهنا مقتطفات من بايثون الوثائق:

iter(o[, sentinel])

عودة التكرار الكائن. ...(قص)... إذا كانت الحجة الثانية ، sentinel, ويرد ، ثم o يجب أن يكون أ للاستدعاء الكائن.مكرر التي تم إنشاؤها في هذه الحالة سيتم استدعاء o مع عدم وجود حجج كل دعوة إلى next() الأسلوب ؛ إذا كانت القيمة التي تم إرجاعها يساوي sentinel, StopIteration سوف تثار ، وإلا سوف تكون القيمة التي تم إرجاعها.

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

def next():
   for num in range(10):
      yield num

for x in next():
   print x

ربما ليس بشكل رهيب الاصطلاحية ، ولكن أود أن يكون يميلون إلى الذهاب مع

x = next()
while x != END:
    do_something_with_x
    x = next()

...ولكن هذا لأنني أجد هذا النوع من الشيء السهل قراءة

ماذا تحاول أن تفعل هنا ؟ إذا كنت بالتكرار أكثر من قائمة ، يمكنك استخدام for e in L حيث e هو عنصر L لائحة.إذا كنت تصفية القائمة ، يمكنك استخدام قائمة comprehensions (أي [ e for e in L if e % 2 == 0 ] الحصول على جميع الأرقام حتى في القائمة).

يمكنك توفير المزيد من المعلومات عن ما كنت تحاول إنجاز ؟ ليس واضحا لي لماذا لا يمكنك فقط أن أقول

for x in everything():
    ...

ويكون كل وظيفة عودة كل شيء, بدلا من كتابة الدالة التالية إلى العودة فقط شيء واحد في وقت واحد.مولدات حتى يمكن القيام بذلك بكفاءة تامة.

إذا كنت بحاجة إلى القيام بذلك أكثر من مرة ، pythonic طريقة استخدام مكرر

for x in iternext():
    do_something_with_x

حيث iternext سوف يتم تحديد استخدام شيء من هذا القبيل (صراحة أفضل من ضمني!):

def iternext():
    x = next()
    while x != END:
        yield x
        x = next()        
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top