أنظف طريقة للحصول على العنصر الأخير من بيثون مكرر

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

سؤال

ما هي أفضل طريقة للحصول على العنصر الأخير من مكرر في بيثون 2.6?على سبيل المثال ، قل

my_iter = iter(range(5))

ما هو أقصر رمز / أنظف طريقة للحصول على 4 من عند my_iter?

يمكنني القيام بذلك ، لكنه لا يبدو فعالا للغاية:

[x for x in my_iter][-1]
هل كانت مفيدة؟

المحلول

item = defaultvalue
for item in my_iter:
    pass

نصائح أخرى

إستخدم deque من الحجم 1.

from collections import deque

#aa is an interator
aa = iter('apple')

dd = deque(aa, maxlen=1)
last_element = dd.pop()

إذا كنت تستخدم Python 3.x:

*_, last = iterator # for a better understanding check PEP 448
print(last)

إذا كنت تستخدم Python 2.7:

last = next(iterator)
for last in iterator:
    continue
print last


NB:

عادةً ما يكون الحل الوارد أعلاه هو ما تحتاجه لحالات منتظمة ، ولكن إذا كنت تتعامل مع كمية كبيرة من البيانات ، فمن أكثر فعالية استخدام أ deque من الحجم 1. (مصدر)

from collections import deque

#aa is an interator
aa = iter('apple')

dd = deque(aa, maxlen=1)
last_element = dd.pop()

ربما يستحق استخدام __reversed__ إذا كانت متوفرة

if hasattr(my_iter,'__reversed__'):
    last = next(reversed(my_iter))
else:
    for last in my_iter:
        pass

ببساطة:

max(enumerate(the_iter))[1]

من غير المرجح أن يكون هذا أسرع من الفارغ للحلقة بسبب لامدا ، ولكن ربما يعطي شخص آخر فكرة

reduce(lambda x,y:y,my_iter)

إذا كان ITER فارغًا ، يتم رفع نوع

هناك هذا

list( the_iter )[-1]

إذا كان طول التكرار ملحميًا حقًا - منذ فترة طويلة لدرجة أن تجسيد القائمة سوف يستنفد الذاكرة - فأنت بحاجة حقًا إلى إعادة التفكير في التصميم.

سأستخدم reversed, ، باستثناء أنه لا يتطلب سوى التسلسلات بدلاً من التكرار ، والذي يبدو تعسفيًا إلى حد ما.

بأي طريقة تفعل ذلك ، يجب عليك الركض عبر التكرار بأكمله. بأقصى قدر من الكفاءة ، إذا لم تكن بحاجة إلى التكرار مرة أخرى ، فيمكنك فقط تفعيل كل القيم:

for last in my_iter:
    pass
# last is now the last item

أعتقد أن هذا حل دون المستوى الأمثل.

ال Toolz توفر المكتبة حلاً لطيفًا:

from toolz.itertoolz import last
last(values)

لكن إضافة التبعية غير الأساسية قد لا تستحق ذلك لاستخدامها فقط في هذه الحالة.

انظر هذا الرمز لشيء مشابه:

http://excamera.com/sphinx/article-islast.html

يمكنك استخدامه لالتقاط العنصر الأخير بـ:

[(last, e) for (last, e) in islast(the_iter) if last]

سأستخدم فقط next(reversed(myiter))

السؤال يتعلق بالحصول على العنصر الأخير من التكرار ، ولكن إذا تم إنشاء التكرار الخاص بك عن طريق تطبيق الظروف على تسلسل ، فيمكن استخدام عكس للعثور على "الأول" للتسلسل العكسي ، فقط النظر إلى العناصر المطلوبة ، من خلال تطبيق عكس التسلسل نفسه.

مثال مفتعل ،

>>> seq = list(range(10))
>>> last_even = next(_ for _ in reversed(seq) if _ % 2 == 0)
>>> last_even
8

بدلاً من ذلك بالنسبة للتكرار اللانهائي يمكنك استخدامه:

from itertools import islice 
last = list(islice(iterator(), 1000))[-1] # where 1000 is number of samples 

اعتقدت أنه سيكون أبطأ بعد ذلك deque لكنه سريع وهو في الواقع أسرع ثم لطريقة الحلقة (بطريقة ما)

السؤال خاطئ ويمكن أن يؤدي فقط إلى إجابة معقدة وغير فعالة. للحصول على جهاز التكرار ، تبدأ بالطبع من شيء أمر لا يطاق ، والذي سيوفر في معظم الحالات طريقة أكثر مباشرة للوصول إلى العنصر الأخير.

بمجرد أن تقوم بإنشاء جهاز التكرار من أحدهم ، فإنك عالق في مرور العناصر ، لأن هذا هو الشيء الوحيد الذي يوفره الأمر.

لذلك ، فإن الطريقة الأكثر كفاءة وواضحة هي عدم إنشاء التكرار في المقام الأول ولكن استخدام طرق الوصول الأصلي للمعدة.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top