أنظف طريقة للحصول على العنصر الأخير من بيثون مكرر
-
22-09-2019 - |
سؤال
ما هي أفضل طريقة للحصول على العنصر الأخير من مكرر في بيثون 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
لكنه سريع وهو في الواقع أسرع ثم لطريقة الحلقة (بطريقة ما)
السؤال خاطئ ويمكن أن يؤدي فقط إلى إجابة معقدة وغير فعالة. للحصول على جهاز التكرار ، تبدأ بالطبع من شيء أمر لا يطاق ، والذي سيوفر في معظم الحالات طريقة أكثر مباشرة للوصول إلى العنصر الأخير.
بمجرد أن تقوم بإنشاء جهاز التكرار من أحدهم ، فإنك عالق في مرور العناصر ، لأن هذا هو الشيء الوحيد الذي يوفره الأمر.
لذلك ، فإن الطريقة الأكثر كفاءة وواضحة هي عدم إنشاء التكرار في المقام الأول ولكن استخدام طرق الوصول الأصلي للمعدة.