পাইথন ইটারেটর থেকে শেষ আইটেমটি পাওয়ার সবচেয়ে সহজ উপায়


110

পাইথন ২.6 এ একটি পুনরুক্তিকারীর কাছ থেকে সর্বশেষ আইটেমটি পাওয়ার সর্বোত্তম উপায় কী? উদাহরণস্বরূপ, বলুন

my_iter = iter(range(5))

সবচেয়ে কম-কোড / পাবার পরিষ্কার উপায় কী 4থেকে my_iter?

আমি এটি করতে পারি, তবে এটি খুব দক্ষ বলে মনে হচ্ছে না:

[x for x in my_iter][-1]

4
Iteters অনুমান যে আপনি উপাদানগুলির মাধ্যমে পুনরাবৃত্তি করতে চান এবং শেষ উপাদানগুলি সত্যই অ্যাক্সেস করতে চান না। (5) [- 1] সীমাবদ্ধভাবে কেবল ব্যবহার করা থেকে আপনাকে কী বাধা দেয়?
ফ্র্যাঙ্ক

7
@ ফ্র্যাঙ্ক - আমি ধরে নিয়েছিলাম যে আসল পুনরুক্তিকারী আরও জটিল এবং / বা আরও দূরে এবং / অথবা এর চেয়ে বেশি কঠোর ছিলiter(range(5))
ক্রিস লুটজ

3
@ ফ্র্যাঙ্ক: সত্য যে এটি আসলে আরও জটিল জেনারেটর ফাংশন যা পুনরুক্তি সরবরাহ করে। আমি কেবল এই উদাহরণটি তৈরি করেছি যাতে এটি সহজ এবং স্পষ্ট হয় যা ঘটছিল।
পিটার

4
যদি আপনি কোনও পুনরুক্তিকারীর শেষ আইটেমটি চান তবে আপনার কিছু ভুল করার খুব বড় সম্ভাবনা রয়েছে। তবে উত্তরটি হ'ল সত্যিকারের কোনও পরিষ্কার উপায় নেই যা পুনরুক্তির মাধ্যমে পুনরুক্তি করে। এটি কারণ কারণ পুনরাবৃত্তকারীগুলির একটি আকার থাকে না এবং প্রকৃতপক্ষে কখনও কখনও শেষ হয় না এবং যেমন কোনও শেষ আইটেম নাও থাকতে পারে। (মানে আপনার কোড অবশ্যই চিরকাল চলবে)। সুতরাং অলস প্রশ্নটি: আপনি কেন একজন পুনরুক্তিকারীর শেষ আইটেমটি চান?
লেনার্ট রেগেব্রো

3
@ পিটার: আপনার প্রশ্ন আপডেট করুন, দয়া করে। নিজের মালিকানাধীন একটি প্রশ্নের সাথে একগুচ্ছ মন্তব্য যুক্ত করবেন না। প্রশ্ন আপডেট করুন এবং মন্তব্যগুলি সরান।
এস .লট

উত্তর:


100
item = defaultvalue
for item in my_iter:
    pass

4
স্থানধারক কেন "ডিফল্ট মূল্য"? কেন হবে না None? এটি ঠিক কি Noneজন্য হয়। আপনি কি পরামর্শ দিচ্ছেন যে কিছু ফাংশন-নির্দিষ্ট ডিফল্ট মান এমনকি সঠিক হতে পারে? যদি পুনরুক্তিকারীটি প্রকৃতপক্ষে পুনরাবৃত্তি না করে তবে একটি বিভ্রান্তিকর ফাংশন-নির্দিষ্ট ডিফল্টের চেয়ে আউট-অফ-ব্যান্ড মানটি আরও অর্থবহ।
এস .লট

46
ডিফল্ট মূল্য আমার উদাহরণের জন্য কেবল একটি স্থানধারক। আপনি যদি Noneডিফল্ট মান হিসাবে ব্যবহার করতে চান তবে এটি আপনার পছন্দ। কোনওটিই সর্বদা বুদ্ধিমান ডিফল্ট নয় এবং এমনকি ব্যান্ডের বাইরেও না। এটি সত্যই অনন্য একটি মান নিশ্চিত করার জন্য ব্যক্তিগতভাবে আমি 'ডিফল্টমূল্য = অবজেক্ট ()' ব্যবহার করি। আমি কেবল ইঙ্গিত দিচ্ছি যে ডিফল্টের পছন্দটি এই উদাহরণের আওতার বাইরে।
থমাস ওয়াটারস

28
@ এস.লট: সম্ভবত এটি একটি Noneচূড়ান্ত মান হিসাবে একটি খালি পুনরাবৃত্তি এবং একটি পুনরাবৃত্তির মধ্যে পার্থক্য পার্থক্য করতে দরকারী
জন লা রুই

8
সমস্ত বিল্টিন কনটেইনার ধরণের সমস্ত পুনরাবৃত্তিতে একটি ডিজাইনের ত্রুটি আছে? আমি প্রথমবার এটি শুনেছি :)
টমাস ওয়াউটারস

7
যদিও এটি সম্ভবত দ্রুত সমাধান, এটি ফর-লুপগুলিতে ভেরিয়েবল লিকের উপর নির্ভর করে (কারও কারও জন্য একটি বৈশিষ্ট্য, অন্যদের জন্য একটি বাগ - সম্ভবত এফপি-ছেলেরা হতবাক হয়ে গেছে)। যাইহোক, গাইডো বলেছিলেন এটি এটি সর্বদা এভাবে কাজ করবে, সুতরাং এটি ব্যবহারের জন্য নিরাপদ নির্মাণ।
টোকল্যান্ড

68

dequeআকার 1 ব্যবহার করুন ।

from collections import deque

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

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

6
লুপের চেয়ে কেবল স্বল্পতম দ্রুততর হওয়া সত্ত্বেও এটি দীর্ঘতম ক্রমটি নিঃশেষ করার দ্রুততম উপায়।
সোভেন মার্নাচ

11
প্রযুক্তিগতভাবে সঠিক হওয়ার জন্য +1, তবে পাঠকদের কাছে সাধারণ পাইথন ক্যাটাটস থাকা উচিত, "আপনার কি এটিকে আরও অনুকূলিতকরণের দরকার?", "এটি কম স্পষ্ট, যা পাইথোনিক নয়", এবং "দ্রুত গতি বাস্তবায়নের উপর নির্ভর করে, যা পরিবর্তন হতে পারে."
লিউজ

1
এছাড়াও, এটি একটি স্মৃতি-হগ
Eelco হুগেনডোরন

6
পছন্দ করুন
ক্রিস ওয়েসলিং 13

1
এখনও অবধি এখানে উপস্থাপিত সমস্ত সমাধান থেকে আমি এটিকে দ্রুত এবং সর্বাধিক মেমরির দক্ষ বলে মনে করি
মার্কাস স্ট্রাউস

66

যদি আপনি পাইথন 3.x ব্যবহার করেন:

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

যদি আপনি পাইথন ২.7 ব্যবহার করেন:

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


সাইড নোট:

সাধারণত, উপরোক্ত সমাধানটি হ'ল নিয়মিত ক্ষেত্রে আপনার যা প্রয়োজন তা হ'ল তবে আপনি যদি প্রচুর পরিমাণে ডেটা dequeনিয়ে কাজ করে থাকেন তবে আকারের 1 ব্যবহার করা আরও দক্ষ efficient ( উত্স )

from collections import deque

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

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

1
@ ভার্চুয়াল টেক্সট: আন্ডারস্কোরটি কেবল একটি সনাক্তকারী। সামনে তারকা বলেছিলেন "তালিকাটি প্রসারিত করুন"। আরও পাঠযোগ্য হবে *lst, last = some_iterable
পিআরপি

4
@ ভার্চুয়াল টেক্সট নোপ _পাইথনের বিশেষ পরিবর্তনশীল এবং এটি সর্বশেষ মান সংরক্ষণ করতে বা এই মানটি সম্পর্কে যত্ন নেয় না বলে পরিষ্কার করা যায় বলে ব্যবহৃত হয়।
ধিয়াটিএন

1
পাইথন 3 সমাধানটি মেমোরি-দক্ষ নয়।
মার্কাস স্ট্রাউস

3
@ ধিয়াটিএন হ্যাঁ, আপনি একেবারে ঠিক বলেছেন। আসলে, পাইথন 3 আইডিয়ামটি আপনি পছন্দ করেছেন you আমি কেবল পরিষ্কার করতে চেয়েছিলাম, এটি "বিগ ডেটা" এর জন্য কাজ করে না। আমি সেগুলির জন্য সংগ্রহে ডেস্ক ব্যবহার করি যা দ্রুত এবং স্মৃতিশক্তির দক্ষ হতে দেখা যায় (মার্টিন 23487234 থেকে সমাধান দেখুন)।
মার্কাস স্ট্রাস

1
এই পাই 3.5 + উদাহরণটি পিইপি 448 হওয়া উচিত W বিস্ময়কর।
এলিয়াদএল

33

__reversed__এটি উপলব্ধ থাকলে সম্ভবত মূল্যবান

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

27

মতই সহজ:

max(enumerate(the_iter))[1]

8
ওহ, এটি চালাক সর্বাধিক দক্ষ বা পঠনযোগ্য নয়, তবে চালাক।
টিমেজব

6
সুতরাং কেবল উচ্চস্বরে চিন্তা করা ... এটি কাজ করে কারণ enumerateএরূপ (index, value): (0, val0), (1, val1), (2, val2)... এবং তারপরে ডিফল্টরূপে maxযখন টিপলগুলির একটি তালিকা দেওয়া হয়, কেবলমাত্র দুটি প্রাথমিক মান সমান না হলে, কেবলমাত্র টিউলের প্রথম মানের সাথে তুলনা করা হয়, যা তারা এখানে কখনই নেই which কারণ তারা সূচকগুলি উপস্থাপন করে। তারপরে চলমান সাবস্ক্রিপ্টটি হ'ল কারণ সর্বাধিক পুরো (আইডেক্স, মান) টুপল দেয় যখন আমরা কেবল আগ্রহী value। আকর্ষণীয় ধারণা।
টেলর এডমিস্টন

21

ল্যাম্বডায়ার কারণে এটি খালি ফাঁকের চেয়ে দ্রুততর হওয়ার সম্ভাবনা নেই তবে সম্ভবত এটি অন্য কাউকে ধারণা দেবে

reduce(lambda x,y:y,my_iter)

যদি এটির খালি থাকে তবে একটি টাইপরর উত্থাপিত হয়


আইএমএইচও, ধারণাগতভাবে এটি সবচেয়ে সর্বাধিক প্রত্যক্ষ। TypeErrorখালি পুনরাবৃত্তির জন্য উত্থাপনের পরিবর্তে , আপনি প্রাথমিক মান reduce(), যেমন, এর মাধ্যমে একটি ডিফল্ট মান সরবরাহ করতে পারেন last = lambda iterable, default=None: reduce(lambda _, x: x, iterable, default)
egnha

9

এই আছে

list( the_iter )[-1]

যদি পুনরাবৃত্তির দৈর্ঘ্য সত্যই মহাকাব্য হয় - এত দীর্ঘ যে তালিকাটি কার্যকর করার ফলে মেমরিটি নিঃশেষ হয়ে যাবে - তাহলে আপনাকে সত্যই ডিজাইনটি পুনর্বিবেচনা করতে হবে।


1
এটি সবচেয়ে সহজ সমাধান।
লাইক

2
একটি টিপল ব্যবহার করার জন্য হালকাভাবে আরও ভাল।
ক্রিস্টোফার স্মিথ

9
শেষ বাক্যটির সাথে দৃ disag়ভাবে একমত নন। খুব বড় ডেটাসেটের সাথে কাজ করা (এটি একবারে সমস্ত লোড করা হলে মেমরির সীমা ছাড়িয়ে যেতে পারে) তালিকার পরিবর্তে পুনরুক্তি ব্যবহারের প্রধান কারণ।
পল

@ পল: কিছু ফাংশন কেবল একটি পুনরাবৃত্তিকে ফেরত দেয়। এটি সেই ক্ষেত্রে (অ-মহাকাব্য তালিকার জন্য) এটি করার একটি স্বল্প ও সুন্দর পাঠযোগ্য উপায়।
সার্ভ-ইনক

এটি সবচেয়ে খারাপ কার্যকর উপায় যা খারাপ খারাপ খারাপ অভ্যাস হিসাবে এড়ানো উচিত। সিকোয়েন্সের সর্বাধিক উপাদান পাওয়ার জন্য আর একটি হ'ল সাজান (ক্রম) [- 1] ব্যবহার করা। আপনি যদি সফটওয়্যার ইঞ্জিনিয়ার হতে চান তবে দয়া করে কখনই এই অসুস্থ প্যাটার্নগুলি ব্যবহার করবেন না।
ম্যাকসেম গ্যানেনকো

5

আমি ব্যবহার করব reversed , এটি ব্যতীত কেবল পুনরাবৃত্তির পরিবর্তে সিকোয়েন্স নেয়, যা স্বেচ্ছাসেবী বলে মনে হয়।

যেভাবেই আপনি এটি করেন না কেন, আপনাকে পুরো পুনরুক্তি দিয়ে চালাতে হবে। সর্বাধিক দক্ষতায়, যদি আপনার আর কখনও পুনরুক্তি প্রয়োজন না হয়, আপনি কেবল সমস্ত মান ট্র্যাশ করতে পারেন:

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

যদিও আমি মনে করি এটি একটি উপ-অনুকূল সমাধান, যদিও।


4
বিপরীত () একটি পুনরাবৃত্তি গ্রহণ করে না, কেবল সিকোয়েন্সগুলি।
টমাস ওয়াটারস

3
এটি মোটেও স্বেচ্ছাচারিতা নয়। কোনও আইট্রেটরকে বিপরীত করার একমাত্র উপায় হ'ল সমস্ত আইটেমকে স্মৃতিতে রেখেই শেষ পর্যন্ত পুনরাবৃত্তি করা। আমি, ই, আপনাকে প্রথমে এটির বিপরীতমুখী করার আগে আপনাকে এটির একটি ক্রম তৈরি করতে হবে। কোনটি অবশ্যই প্রথম স্থানে পুনরাবৃত্তির উদ্দেশ্যকে পরাজিত করে এবং এর অর্থ হ'ল আপনি হঠাৎ কোনও স্পষ্ট কারণ ছাড়াই প্রচুর স্মৃতি ব্যবহার করেন। সুতরাং এটি বাস্তবে বিপরীত। :)
লেনার্ট রেগেব্রো

@ লেনার্ট - যখন আমি নির্বিচারে বলি, আমি বিরক্তিকর বলতে চাইছি। আমি এই সময় সকালে এই সময়ে কয়েক ঘন্টার কারণে আমার কাগজগুলিতে আমার ভাষার দক্ষতা ফোকাস করছি।
ক্রিস লুটজ

3
যথেষ্ট ফর্সা। যদিও আইএমও এটি পুনরুক্তিকারীদের গ্রহণ না করলে এটি আরও বিরক্তিকর হবে, কারণ এর প্রায় কোনও ব্যবহারই একটি খারাপ ধারণা (টিএম) হবে। :)
লেনার্ট রেজেব্রো

3

Toolz গ্রন্থাগার একটা চমৎকার সমাধান প্রদান করে:

from toolz.itertoolz import last
last(values)

তবে নন-কোর নির্ভরতা যুক্ত করা কেবলমাত্র এই ক্ষেত্রে এটি ব্যবহারের জন্য উপযুক্ত নাও হতে পারে।


1

অনুরূপ কিছুর জন্য এই কোডটি দেখুন:

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

আপনি এটি শেষ আইটেমটি বাছাই করতে ব্যবহার করতে পারেন:

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

1
islastআপনার উত্তরের জন্য দয়া করে কোডটি অন্তর্ভুক্ত করুন ( মেটা.স্ট্যাকেক্সচেঞ্জ / প্রশ্ন / ৮২৩১/২ দেখুন )।
ক্রিশ্চিয়ান সিউপিতু

0

আমি শুধু ব্যবহার করতে হবে next(reversed(myiter))


8
প্রকারের ত্রুটি: বিপরীতে যুক্ত হওয়া () অবশ্যই একটি ক্রম হতে হবে
ল্যাবো

0

প্রশ্নটি একটি পুনরুক্তকারীর শেষ উপাদানটি পাওয়ার বিষয়ে, তবে যদি আপনার পুনরুক্তিটি একটি অনুক্রমের শর্ত প্রয়োগ করে তৈরি করা হয়, তবে বিপরীতগুলি বিপরীত ক্রমের "প্রথম" সন্ধান করতে ব্যবহার করা যেতে পারে, কেবলমাত্র প্রয়োগ করে প্রয়োজনীয় উপাদানগুলির সন্ধান করতে ক্রম নিজেই বিপরীত।

একটি স্বীকৃত উদাহরণ,

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

0

বিকল্প হিসাবে আপনি ব্যবহার করতে পারেন অসীম পুনরুক্তিদের জন্য:

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

আমি ভেবেছিলাম এটি তখন ধীর হবে dequeতবে এটি তত দ্রুত এবং লুপ পদ্ধতির জন্য এটি আসলে দ্রুততর (একরকম)


-6

প্রশ্নটি ভুল এবং কেবল এমন একটি উত্তর নিয়ে যেতে পারে যা জটিল এবং অদক্ষ। একটি পুনরুক্তি পেতে, আপনি অবশ্যই পুনরাবৃত্তিযোগ্য এমন কোনও কিছু থেকে শুরু করবেন যা বেশিরভাগ ক্ষেত্রে শেষ উপাদানটিতে অ্যাক্সেসের আরও প্রত্যক্ষ উপায় সরবরাহ করবে।

একবার আপনি কোনও পুনরাবৃত্তিযোগ্য থেকে একটি পুনরাবৃত্তি তৈরি করার পরে আপনি উপাদানগুলির মধ্যে যেতে আটকে যাবেন, কারণ এটিই কেবল পুনরাবৃত্তিযোগ্য সরবরাহ করে।

সুতরাং, সর্বাধিক দক্ষ এবং সুস্পষ্ট উপায় হ'ল প্রথম স্থানে পুনরুক্তি তৈরি করা নয় বরং পুনরাবৃত্তকারীগুলির নেটিভ অ্যাক্সেস পদ্ধতি ব্যবহার করা।


5
সুতরাং আপনি কিভাবে একটি ফাইলের শেষ লাইন পাবেন?
ব্রাইস এম। ডেম্পসে

@ ব্রাইসএম.ডেম্পসে সবচেয়ে ভাল উপায়টি পুরো (সম্ভবত বিশাল) ফাইলটি পুনরাবৃত্তি করে নয়, তবে ফাইলের আকার মাইনাস 100 এ গিয়ে শেষ 100 বাইট পড়ুন, সেগুলিতে একটি নতুন লাইনের জন্য স্ক্যান করুন, যদি না থাকে তবে যান অন্য ১০০ বাইট ইত্যাদির পিছনে ফিরে যান ইত্যাদি আপনার দৃশ্যের উপর নির্ভর করে আপনি আপনার স্টেপ-ব্যাক আকারটিও বাড়িয়ে তুলতে পারেন। অবশ্যই গাজিলিয়ন লাইন পড়া একটি অনুকূল-সমাধান নয়।
আলফ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.