পাইথনে [] ছাড়াই উপলব্ধি তালিকাভুক্ত করুন


86

একটি তালিকায় যোগদান:

>>> ''.join([ str(_) for _ in xrange(10) ])
'0123456789'

join অবশ্যই পুনরাবৃত্ত হওয়া উচিত take

স্পষ্টতই, joinযুক্তিটি হল [ str(_) for _ in xrange(10) ], এবং এটি একটি তালিকা বোধগম্য

এটা দেখ:

>>>''.join( str(_) for _ in xrange(10) )
'0123456789'

এখন, joinযুক্তি ন্যায়সঙ্গত str(_) for _ in xrange(10), না [], তবে ফলাফল একই।

কেন? না str(_) for _ in xrange(10)আরো একটি তালিকা অথবা একটি iterable উত্পাদন?


4
আমি কল্পনা করব যে joinএটি সম্ভবত সি তে লেখা হয়েছে এবং তাই তালিকা বোধগমণের চেয়ে অনেক দ্রুত চলে ... পরীক্ষার সময়!
জোয়েল করনেট

স্পষ্টতই, আমি আপনার প্রশ্নটি সম্পূর্ণ ভুল পড়েছি। মনে হচ্ছে এটি আমার জন্য কোনও জেনারেটর ফিরিয়ে দিচ্ছে ...
জোয়েল করনেট

18
কেবল একটি নোট: _এর কোনও বিশেষ অর্থ নেই, এটি নিয়মিত পরিবর্তনশীল নাম। এটি প্রায়শই একটি ফেলে দেওয়া নাম হিসাবে ব্যবহৃত হয় তবে এটি ক্ষেত্রে নেই (আপনি ভেরিয়েবলটি ব্যবহার করছেন)। আমি এটিকে কোনও কোডে ব্যবহার করা এড়াতে চাই (অন্তত এভাবে)।
rplnt

উত্তর:


69
>>>''.join( str(_) for _ in xrange(10) )

এটিকে জেনারেটর এক্সপ্রেশন বলা হয় এবং এটি পিইপি 289-এ ব্যাখ্যা করা হয় ।

জেনারেটর এক্সপ্রেশন এবং তালিকা বোঝার মধ্যে প্রধান পার্থক্য হ'ল প্রাক্তন মেমরিতে তালিকা তৈরি করে না।

দ্রষ্টব্য যে এক্সপ্রেশনটি লেখার তৃতীয় উপায় রয়েছে:

''.join(map(str, xrange(10)))

4
আমি এটি জানি, একটি জেনারেটর একটি টিপল-মত মত প্রকাশের মাধ্যমে উত্পাদন করা যেতে পারে, মত ( str(_) for _ in xrange(10) )। তবে আমি বিভ্রান্ত হয়ে পড়েছিলাম যে, কেন ()বাদ দেওয়া যেতে পারে join, যার অর্থ কোডটি '' 'এর মতো হওয়া উচিত x
অ্যালকোট

4
@ অ্যালকোট আমার টিউপস সম্পর্কে আমার বোধগম্যতা হ'ল এগুলি প্রকৃতপক্ষে কমা-বিচ্ছিন্ন এক্সপ্রেশনগুলির তালিকা দ্বারা সংজ্ঞায়িত করা হয়েছে, বন্ধনী নয়; প্রথম বন্ধনী কেবল কোনও অ্যাসাইনমেন্টের মধ্যে ভ্যালুগুলিকে চাক্ষুষভাবে গোষ্ঠীভুক্ত করতে বা টিউপলটি কোনও ফাংশন কলের মতো অন্য কোনও কমা-বিভাজিত তালিকায় চলে যাওয়ার পরে মানগুলিকে গোষ্ঠীভুক্ত করার জন্য রয়েছে। এটি প্রায়শই চলমান কোডের মাধ্যমে প্রদর্শিত হয় tup = 1, 2, 3; print(tup)। এটি মনে রেখে, forএকটি অভিব্যক্তির অংশ হিসাবে ব্যবহার করা জেনারেটর তৈরি করে এবং বন্ধুত্বগুলি একটি ভুলভাবে লিখিত লুপ থেকে আলাদা করার জন্য কেবল সেখানে রয়েছে।
এরিক এড লোহমার

133

অন্যান্য উত্তরদাতারা উত্তর দেওয়ার ক্ষেত্রে সঠিক ছিল যে আপনি একটি জেনারেটর এক্সপ্রেশনটি আবিষ্কার করেছেন (এটির তালিকাটি বোঝার সাথে মিল থাকলেও পার্শ্ববর্তী বর্গাকার বন্ধনীগুলি বাদে) ation

সাধারণভাবে, জেনেক্সপ্স (তারা যেমন স্নেহভাজন হিসাবে পরিচিত) তালিকান বোধগমণের চেয়ে বেশি স্মৃতিশক্তি দক্ষ এবং দ্রুত।

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

~ $ python -m timeit '"".join(str(n) for n in xrange(1000))'
1000 loops, best of 3: 335 usec per loop
~ $ python -m timeit '"".join([str(n) for n in xrange(1000)])'
1000 loops, best of 3: 288 usec per loop

Itertools.imap বনাম মানচিত্রের তুলনা করার সময় একই ফলাফলটি ধারণ করে :

~ $ python -m timeit -s'from itertools import imap' '"".join(imap(str, xrange(1000)))'
1000 loops, best of 3: 220 usec per loop
~ $ python -m timeit '"".join(map(str, xrange(1000)))'
1000 loops, best of 3: 212 usec per loop

4
@ লাজির আপনার দ্বিতীয় সময় অনেক বেশি কাজ করছে। কোনও লিস্টকম্পের চারপাশে জিনপ্স মোড়ান না - কেবল একটি জেনপ এক্স ব্যবহার করুন। অবাক হওয়ার মতোই সময় নেই
রেমন্ড হেটেঙ্গার

11
আপনি ব্যাখ্যা করতে পারেন কেন ''.join()স্ট্রিং তৈরির জন্য পুনরুক্তিটির উপরে 2 টি পাসের প্রয়োজন?
ওভোগোলোভিন

28
@ovgolovin আমি অনুমান করেছি যে প্রথম পাসটি স্ট্রিংগুলির দৈর্ঘ্যগুলি যোগ করতে হবে যাতে সংক্ষিপ্ত স্ট্রিংয়ের জন্য সঠিক পরিমাণের মেমরি বরাদ্দ করতে সক্ষম হয়, যখন দ্বিতীয় পাসটি পৃথক স্ট্রিংগুলিকে বরাদ্দকৃত স্থানে অনুলিপি করতে হয়।
লরিজ ভি ভি থালো

20
@ লাজির এই অনুমানটি সঠিক is ঠিক এটিই স্ট্রিং জোইন করে :-)
রেমন্ড

4
কখনও কখনও আমি এসও এর একটি নির্দিষ্ট উত্তর "পছন্দসই" করার ক্ষমতাটি সত্যিই মিস করি।
এয়ার

5

আপনার দ্বিতীয় উদাহরণটি তালিকা বোধের চেয়ে জেনারেটর এক্সপ্রেশন ব্যবহার করে। পার্থক্যটি হল তালিকা অনুধাবন করার সাথে, একটি তালিকা সম্পূর্ণরূপে নির্মিত এবং পাস করা হয় .join()। জেনারেটরের এক্সপ্রেশন সহ আইটেমগুলি একে একে উত্পন্ন হয় এবং সেগুলি গ্রাস করে .join()। পরেরটি কম স্মৃতি ব্যবহার করে এবং সাধারণত দ্রুত হয়।

এটি হওয়ার সাথে সাথে তালিকার নির্মাতা জেনারেটর এক্সপ্রেশন সহ যেকোন পুনরাবৃত্তিকে সুখে গ্রাস করবেন। সুতরাং:

[str(n) for n in xrange(10)]

এটি কেবল "সিনট্যাকটিক চিনি" এর জন্য:

list(str(n) for n in xrange(10))

অন্য কথায়, একটি তালিকা উপলব্ধি কেবল একটি জেনারেটর এক্সপ্রেশন যা তালিকায় পরিণত হয়।


4
আপনি কি নিশ্চিত যে তারা ফণা নীচে সমতুল্য? টাইমাইট বলেছেন:: [str(x) for x in xrange(1000)]262 ইউজেক list(str(x) for x in xrange(1000)),: 304 ইউজেক।
লরিৎজ ভি। থালো

4
আপনি কি ঠিক বলেছেন তালিকা বোধগতি দ্রুত। এবং এই কারণেই পাইথন ২.x এ তালিকা বোধগম্যতা ফাঁস হয়। জিভিআর এটি লিখেছিলেন: "" এটি তালিকা বোধের মূল প্রয়োগের একটি নিদর্শন ছিল; এটি বছরের পর বছর ধরে পাইথনের অন্যতম "নোংরা ছোট ছোট রহস্য" ছিল। অন্ধভাবে দ্রুত তালিকা বোঝার জন্য এটি ইচ্ছাকৃত আপোস হিসাবে শুরু হয়েছিল এবং এটি প্রাথমিকভাবে কোনও সাধারণ সমস্যা না হলেও এটি মাঝে মাঝে মানুষকে হতবাক করেছিল
হিস্টরি.ব্লগস্পট

4
@ovgolovin লিস্টকম্পটি দ্রুত হওয়ার কারণ হ'ল যোগদানের কাজ শুরু করার আগে একটি তালিকা তৈরি করতে হবে। আপনি যে "ফুটো" উল্লেখ করেছেন এটি কোনও গতির সমস্যা নয় - এর অর্থ কেবলমাত্র লুপ ইন্ডাকশন ভেরিয়েবল তালিকা-সংস্থার বাইরে প্রকাশিত হয়েছে।
রেমন্ড হেটেঙ্গার

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

4
@ovgolovin আপনি str.join কেন এটি সম্পাদন করে তার জন্য একটি লিস্টকম্প বাস্তবায়ন বিশদ থেকে একটি ভুল লিপ তৈরি করেছেন। স্ট্রিং জোইন কোডের প্রথম লাইনগুলির মধ্যে একটি হ'ল seq = PySequence_Fast(orig, "");স্ট্রিং জোন () কল করার সময় তালিকাগুলি তালিকাগুলি বা টিপলসের চেয়ে ধীরে ধীরে চালিত হয় sole আপনি যদি আরও আলোচনা করতে চান তবে চ্যাট শুরু করতে আপনাকে স্বাগত জানাই (আমি পিইপি 289 এর লেখক, LIST_APPEND অপকোডের স্রষ্টা এবং তালিকার () কনস্ট্রাক্টরটি অনুকূল করেছেন), তাই আমার কাছে কিছু আছে ইস্যুটির সাথে পরিচিতি)।
রেমন্ড হেটেঞ্জার

5

যেমনটি উল্লেখ করা হয়েছে এটি একটি জেনারেটর এক্সপ্রেশন

ডকুমেন্টেশন থেকে:

শুধুমাত্র একটি যুক্তিযুক্ত কলগুলিতে প্রথম বন্ধনী বাদ দেওয়া যেতে পারে। বিস্তারিত জানার জন্য বিভাগ কল দেখুন ।


4

যদি এটি পেরেন্সে থাকে তবে বন্ধনীগুলিতে নয়, এটি প্রযুক্তিগতভাবে একটি জেনারেটর এক্সপ্রেশন। জেনারেটর এক্সপ্রেশন প্রথমে পাইথন ২.৪ এ প্রবর্তিত হয়েছিল।

http://wiki.python.org/moin/ জেনারেটর

যোগদানের পরে অংশটি ( str(_) for _ in xrange(10) )নিজেই একটি জেনারেটর এক্সপ্রেশন। আপনি যেমন কিছু করতে পারেন:

mylist = (str(_) for _ in xrange(10))
''.join(mylist)

এবং এর অর্থ ঠিক একই জিনিস যা আপনি উপরের দ্বিতীয় ক্ষেত্রে লিখেছিলেন।

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

আপনার নির্দিষ্ট উদাহরণগুলিতে, তালিকা এবং জেনারেটর সম্ভবত ভয়াবহভাবে আলাদাভাবে সঞ্চালন করে না, তবে সাধারণভাবে আমি জেনারেটর এক্সপ্রেশনগুলি (এবং এমনকি জেনারেটর ফাংশন) যখনই আমি পারি ব্যবহার করতে পছন্দ করি, বেশিরভাগ কারণে যে জেনারেটরের পক্ষে সম্পূর্ণ তালিকার চেয়ে ধীর হওয়া খুব বিরল because বস্তুকরণ।


1

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


0

আপনার দ্বিতীয় joinকলের আর্গুমেন্ট একটি জেনারেটর এক্সপ্রেশন। এটি একটি পুনরাবৃত্তিযোগ্য উত্পাদন করে।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.