सवाल पायथन इटरेटर से अंतिम आइटम प्राप्त करने का सबसे साफ तरीका


पाइथन 2.6 में एक इटरेटर से अंतिम आइटम प्राप्त करने का सबसे अच्छा तरीका क्या है? उदाहरण के लिए, कहें

my_iter = iter(range(5))

प्राप्त करने का सबसे छोटा कोड / साफ तरीका क्या है 4 से my_iter?

मैं यह कर सकता था, लेकिन यह बहुत ही कुशल प्रतीत नहीं होता है:

[x for x in my_iter][-1]

76
2018-01-26 10:53


मूल


Iterators मानते हैं कि आप तत्वों के माध्यम से पुन: प्रयास करना चाहते हैं और वास्तव में अंतिम तत्वों तक नहीं पहुंचना चाहते हैं। रेंज (5) [- 1] का उपयोग करने से आपको क्या रोकता है? - Frank
@ फ्रैंक - मैंने माना कि वास्तविक इटरेटर अधिक जटिल और / या आगे और / या नियंत्रण से कठिन था iter(range(5)) - Chris Lutz
@ फ्रैंक: तथ्य यह है कि यह वास्तव में एक बहुत ही जटिल जेनरेटर फ़ंक्शन है जो इटरेटर की आपूर्ति करता है। मैंने अभी इस उदाहरण को बनाया है ताकि यह सरल और स्पष्ट हो कि क्या हो रहा था। - Peter
यदि आप एक इटरेटर के आखिरी आइटम चाहते हैं, तो आप एक गलत मौका कर रहे हैं। लेकिन जवाब यह है कि वास्तव में कोई क्लीनर तरीका नहीं है जो इटेटरेटर के माध्यम से फिर से चल रहा है। ऐसा इसलिए है क्योंकि इटेटर के पास आकार नहीं है, और वास्तव में, कभी भी समाप्त नहीं हो सकता है, और इस तरह के पास अंतिम वस्तु नहीं हो सकती है। (मतलब है कि आपका कोड हमेशा के लिए चलेगा)। तो सवाल यह है कि: आप एक इटरेटर के आखिरी आइटम क्यों चाहते हैं? - Lennart Regebro
@ पीटर: कृपया अपना प्रश्न अपडेट करें। अपने स्वामित्व वाले प्रश्नों पर टिप्पणियों का एक समूह न जोड़ें। कृपया प्रश्न अपडेट करें और टिप्पणियों को हटा दें। - S.Lott


जवाब:


item = defaultvalue
for item in my_iter:
    pass

70
2018-01-26 10:56



प्लेसहोल्डर "डिफ़ॉल्ट" क्यों? क्यों नहीं None? यह ठीक है क्या None के लिए है। क्या आप सुझाव दे रहे हैं कि कुछ फ़ंक्शन-विशिष्ट डिफ़ॉल्ट मान भी सही हो सकते हैं? यदि इटेटरेटर वास्तव में पुन: सक्रिय नहीं होता है, तो आउट-ऑफ-बैंड मान है अधिक कुछ भ्रामक फ़ंक्शन-विशिष्ट डिफ़ॉल्ट से सार्थक। - S.Lott
डिफ़ॉल्ट उदाहरण मेरे उदाहरण के लिए सिर्फ प्लेसहोल्डर है। यदि आप उपयोग करना चाहते हैं None डिफ़ॉल्ट मान के रूप में, यह आपकी पसंद है। कोई भी हमेशा सबसे समझदार डिफ़ॉल्ट नहीं होता है, और बैंड से भी बाहर नहीं हो सकता है। व्यक्तिगत रूप से मैं यह सुनिश्चित करने के लिए 'defaultvalue = object ()' का उपयोग करता हूं कि यह वास्तव में अद्वितीय मूल्य है। मैं बस यह संकेत दे रहा हूं कि डिफ़ॉल्ट की पसंद इस उदाहरण के दायरे से बाहर है। - Thomas Wouters
@ एसएलओटी: शायद एक खाली इटरेटर और एक इटरेटर के बीच अंतर को अलग करना उपयोगी है None क्योंकि यह अंतिम मूल्य है - John La Rooy
सभी बिल्टिन कंटेनर प्रकारों के सभी इटरेटर में एक डिज़ाइन त्रुटि है? पहली बार मैंने इसके बारे में सुना है :) - Thomas Wouters
हालांकि यह शायद तेज़ समाधान है, यह फोर-लूप में परिवर्तनीय लीकिंग पर निर्भर करता है (कुछ के लिए एक सुविधा, दूसरों के लिए एक बग - शायद एफपी-लोग अचंभित हैं)। किसी भी तरह, Guido ने कहा कि यह हमेशा इस तरह से काम करेगा, तो यह उपयोग करने के लिए सुरक्षित निर्माण है। - tokland


का उपयोग deque आकार 1 का।

from collections import deque

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

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

41
2017-07-02 23:39



यह वास्तव में एक लंबे अनुक्रम को समाप्त करने का सबसे तेज़ तरीका है, हालांकि लूप के लिए केवल स्लीघ्ली तेज है। - Sven Marnach
तकनीकी रूप से सही होने के लिए +1, लेकिन पाठकों के पास सामान्य पाइथन चेतावनी होनी चाहिए, "क्या आपको वास्तव में इसे अनुकूलित करने की आवश्यकता है?", "यह कम स्पष्ट है, जो पाइथनिक नहीं है", और "तेज गति कार्यान्वयन पर निर्भर करती है, जो बदल सकता है।" - leewz
भी, यह एक स्मृति-हॉग है - Eelco Hoogendoorn
@EelcoHoogendoorn यह एक स्मृति-हॉग क्यों है, यहां तक ​​कि अधिकतम 1 के साथ भी? - Chris Wesseling


शायद उपयोग करने लायक है __reversed__ अगर यह उपलब्ध है

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

29
2018-02-05 23:01





यदि आप अजगर 3.x का उपयोग कर रहे हैं:

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

यदि आप अजगर 2.7 का उपयोग कर रहे हैं:

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

22
2018-01-12 19:07



क्या आप कृपया समझा सकते हैं *_ अंश? - virtualxtc
@ virtualxtc जांचें पीईपी 448 अधिक जानकारी के लिए - DhiaTN
@virtualxtc: अंडरस्कोर सिर्फ एक पहचानकर्ता है। सामने वाला सितारा कहता है "सूची का विस्तार करें"। अधिक पठनीय होगा *lst, last = some_iterable। - pepr
@virtualxtc नहीं _ पाइथन में विशेष चर है और अंतिम मूल्य को स्टोर करने के लिए या कहने के लिए उपयोग किया जाता है कि मुझे मूल्य की परवाह नहीं है, इसलिए इसे साफ किया जा सकता है। - DhiaTN


लैम्ब्डा के कारण लूप के लिए खाली से अधिक तेज़ होने की संभावना नहीं है, लेकिन शायद यह किसी और को एक विचार देगा

reduce(lambda x,y:y,my_iter)

यदि इटार खाली है, तो टाइपरर उठाया जाता है


18
2018-01-26 11:59





की तरह सरल:

max(enumerate(the_iter))[1]

16
2018-06-06 11:24



ओह, यह चालाक है। सबसे कुशल या पठनीय नहीं, लेकिन चालाक। - timgeb
तो बस जोर से सोच रहा है ... यह इसलिए काम करता है enumerate रिटर्न (index, value) पसंद: (0, val0), (1, val1), (2, val2)... और फिर डिफ़ॉल्ट रूप से max जब tuples की एक सूची दी जाती है, तो टुपल के केवल पहले मान के विरुद्ध तुलना की जाती है, जब तक कि दो पहले मान बराबर न हों, जो वे यहां कभी नहीं हैं क्योंकि वे सूचकांक का प्रतिनिधित्व करते हैं। फिर पिछली उपस्क्रिप्ट इसलिए होती है क्योंकि अधिकतम संपूर्ण (idx, value) tuple देता है जबकि हम केवल रुचि रखते हैं value। दिलचस्प विचार - Taylor Edmiston


यह है

list( the_iter )[-1]

अगर पुनरावृत्ति की लंबाई वास्तव में महाकाव्य है - इतनी देर तक कि सूची को भौतिक बनाने से स्मृति समाप्त हो जाएगी - तो आपको वास्तव में डिजाइन पर पुनर्विचार करना होगा।


4
2018-01-26 11:42



यह सबसे सरल समाधान है। - laike9m
एक ट्यूपल का उपयोग करने के लिए हल्के ढंग से बेहतर है। - Christopher Smith
अंतिम वाक्य से असहमत असहमत। बहुत बड़े डेटासेट के साथ काम करना (जो एक बार में लोड होने पर मेमोरी सीमाओं से अधिक हो सकता है) एक सूची के बजाय एक इटरेटर का उपयोग करने का मुख्य कारण है। - Paul
@ पॉल: कुछ फ़ंक्शन केवल एक पुनरावर्तक लौटाते हैं। यह उस मामले में (गैर-महाकाव्य सूचियों के लिए) करने के लिए एक छोटा और सुंदर पठनीय तरीका है। - serv-inc


मै इस्तेमाल करूंगा reversed, सिवाय इसके कि यह केवल इटरेटर के बजाय अनुक्रम लेता है, जो मनमाने ढंग से लगता है।

किसी भी तरह से आप इसे करते हैं, आपको पूरे इटरेटर के माध्यम से भागना होगा। अधिकतम दक्षता पर, यदि आपको फिर से इटेटरेटर की आवश्यकता नहीं है, तो आप बस सभी मानों को मिटा सकते हैं:

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

मुझे लगता है कि यह एक उप-इष्टतम समाधान है, हालांकि।


2
2018-01-26 10:57



उलटा () एक इटरेटर नहीं लेता है, बस अनुक्रम। - Thomas Wouters
यह बिल्कुल मनमानी नहीं है। एक इटरेटर को रिवर्स करने का एकमात्र तरीका अंत तक फिर से शुरू करना है, जबकि सभी वस्तुओं को स्मृति में रखना है। मैं, ई, आपको पहले इसे अनुक्रमित करने की आवश्यकता है, इससे पहले कि आप इसे उलट सकें। जो भी पहले स्थान पर इटरेटर के उद्देश्य को हरा देता है, और इसका मतलब यह भी होगा कि अचानक अचानक कोई स्मृति नहीं है। तो वास्तव में, यह मनमाने ढंग से विपरीत है। :) - Lennart Regebro
@Lennart - जब मैंने मनमाने ढंग से कहा, मैं परेशान था। मैं इस समय कुछ घंटों में अपने पेपर पर अपनी भाषा कौशल पर ध्यान केंद्रित कर रहा हूं। - Chris Lutz
काफी उचित। यद्यपि आईएमओ यह अधिक परेशान होगा अगर उसने इटरेटर्स को स्वीकार किया, क्योंकि इसका लगभग कोई भी उपयोग खराब विचार (टीएम) होगा। :) - Lennart Regebro


इस कोड को इसी तरह के लिए देखें:

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

आप इसका अंतिम आइटम चुनने के लिए इसका उपयोग कर सकते हैं:

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

1
2018-01-12 18:08



कृपया कोड शामिल करें islast आपके उत्तर में (देखें meta.stackexchange.com/questions/8231/...)। - Cristian Ciupitu


मैं बस उपयोग करूंगा next(reversed(myiter))


0
2017-10-24 18:48



TypeError: उलट करने के लिए तर्क () एक अनुक्रम होना चाहिए - Labo