লিম্বদা + ফিল্টার বোধগম্য তালিকা


857

আমি নিজেকে ফিল্টারিংয়ের একটি মৌলিক প্রয়োজনীয়তা খুঁজে পেয়েছি: আমার একটি তালিকা আছে এবং আইটেমগুলির একটি বৈশিষ্ট্য দ্বারা আমাকে এটি ফিল্টার করতে হবে।

আমার কোডটি এরকম দেখাচ্ছে:

my_list = [x for x in my_list if x.attribute == value]

তবে আমি ভেবেছিলাম, এভাবে লেখা কি ভাল হয় না?

my_list = filter(lambda x: x.attribute == value, my_list)

এটি আরও পঠনযোগ্য, এবং যদি পারফরম্যান্সের প্রয়োজন হয় তবে ল্যাম্বডা কিছু পাওয়ার জন্য নেওয়া যেতে পারে।

প্রশ্নটি হ'ল: দ্বিতীয় উপায়টি ব্যবহার করার ক্ষেত্রে কি কোনও গুপ্তচর রয়েছে? কোন পারফরম্যান্স পার্থক্য? আমি কি পাইথোনিক ওয়ে অনুপস্থিত ™ পুরোপুরি এবং এটি অন্য কোনও উপায়ে করা উচিত (যেমন ল্যাম্বদার পরিবর্তে আইটেমটার ব্যবহার করা)?


19
এর চেয়ে ভাল উদাহরণ এমন একটি ক্ষেত্রে হতে পারে যেখানে আপনার শিকার হিসাবে ব্যবহার করার জন্য আপনার ইতিমধ্যে একটি সুন্দর নামযুক্ত ফাংশন ছিল। সেক্ষেত্রে আমার ধারণা, আরও অনেক লোক এতে সম্মত হবে যে filterএটি আরও পাঠযোগ্য। যখন আপনার কাছে একটি সরল অভিব্যক্তি থাকে যা তালিকার কম্পিউটারে যেমন হয় তেমন ব্যবহার করা যেতে পারে তবে ল্যাম্বডায় (বা অনুরূপভাবে নির্মিত partialবা operatorফাংশন ইত্যাদি) আবৃত করতে হয় filter, যখন লাস্টকম্পস জিতে থাকে।
31-15

3
এটি বলা উচিত যে পাইথন 3-এ অন্ততপক্ষে, প্রত্যাবর্তনটি filterফিল্টার জেনারেটরের কোনও তালিকা নয়।
মাত্তেও ফেরেলা

উত্তর:


588

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

দুটি জিনিস যা আপনার ব্যবহারকে কমিয়ে দিতে পারে filter

প্রথমটি হ'ল ফাংশন কল ওভারহেড: আপনি পাইথন ফাংশনটি ব্যবহার করার সাথে সাথেই ( সম্ভবত এটি তৈরি করেছেন defবা না lambda) সম্ভবত ফিল্টারটি তালিকা বোধের চেয়ে ধীর হয়ে যাবে। এটি প্রায় নিশ্চিতভাবেই যথেষ্ট নয়, এবং আপনি আপনার কোডটি সময় নির্ধারণ না করে এবং এটি কোনও বাধা হিসাবে খুঁজে না পাওয়া পর্যন্ত পারফরম্যান্স সম্পর্কে খুব বেশি চিন্তা করবেন না, তবে পার্থক্য সেখানেই থাকবে।

অন্যান্য ওভারহেড যা প্রয়োগ করতে পারে তা হ'ল ল্যাম্বদা একটি স্কোপড ভেরিয়েবল ( value) অ্যাক্সেস করতে বাধ্য হচ্ছে । এটি স্থানীয় ভেরিয়েবল অ্যাক্সেসের চেয়ে ধীর এবং পাইথন ২.x-এ তালিকার বোধগম্যতা কেবলমাত্র স্থানীয় ভেরিয়েবলগুলি অ্যাক্সেস করে। আপনি যদি পাইথন ৩.x ব্যবহার করে থাকেন তবে তালিকার বোঝাপড়াটি একটি পৃথক ফাংশনে চলে তাই এটি valueবন্ধের মাধ্যমেও অ্যাক্সেস করা হবে এবং এই পার্থক্য প্রযোজ্য হবে না।

বিবেচনা করার জন্য অন্য বিকল্পটি হল তালিকা বোঝার পরিবর্তে একটি জেনারেটর ব্যবহার করা:

def filterbyvalue(seq, value):
   for el in seq:
       if el.attribute==value: yield el

তারপরে আপনার মূল কোডে (যা সেখানে পাঠযোগ্যতা সত্যিই গুরুত্বপূর্ণ) আপনি তালিকা বোঝার এবং ফিল্টার উভয়কে একটি আশাবাদী অর্থপূর্ণ কার্যকরী নাম দিয়ে প্রতিস্থাপন করেছেন।


68
জেনারেটরের জন্য +1। আমার বাড়িতে একটি উপস্থাপনাটির লিঙ্ক রয়েছে যা দেখায় যে জেনারেটরগুলি কী আশ্চর্যজনক হতে পারে। এছাড়াও আপনি শুধু পরিবর্তন করে জেনারেটরের অভিব্যক্তি সঙ্গে তালিকা ধী প্রতিস্থাপন করতে পারেন []থেকে ()। এছাড়াও, আমি সম্মত হই যে তালিকা কমপটি আরও সুন্দর।
ওয়েন ওয়ার্নার

1
আসলে, না - ফিল্টার দ্রুত। শুধু ভালো কিছু ব্যবহার দ্রুত benchmarks দুয়েক চালানো stackoverflow.com/questions/5998245/...
skqr

2
@ এসকিউআর কেবলমাত্র বেঞ্চমার্কের জন্য টাইমিট ব্যবহার করা ভাল তবে দয়া করে একটি উদাহরণ দিন যেখানে আপনি filterপাইথন কলব্যাক ফাংশনটি ব্যবহার করে দ্রুত be
ডানকান

8
@ tnq177 এটি জেনারেটরগুলিতে ডেভিড ব্যাসলির উপস্থাপনা - dabeaz.com
ওয়েন ওয়ার্নার

2
@ ভিক্টরশ্রেডার হ্যাঁ, সম্ভবত আমি অস্পষ্ট ছিলাম। আমি যা বলার চেষ্টা করছিলাম সেটি হ'ল মূল কোডটিতে আপনার বড় ছবি দেখতে সক্ষম হওয়া দরকার। সামান্য সহায়ক ফাংশনে আপনাকে কেবল সেই এক ফাংশনটির যত্ন নেওয়া দরকার, বাইরে আর কী চলছে তা এড়ানো যায়।
ডানকান

237

পাইথনের এটি কিছুটা ধর্মীয় বিষয়। যদিও গাইডো সরানোর বিবেচিত map, filterএবং reduceপাইথন 3 থেকে , একটি নেতিবাচক প্রতিক্রিয়া যে শেষ শুধুমাত্র যথেষ্ট ছিল reduceনির্মান-ইনগুলি থেকে সরিয়ে নেওয়া হয়েছে functools.reduce

ব্যক্তিগতভাবে আমি তালিকার বোধগম্যগুলি সহজভাবে পড়তে পাই। [i for i in list if i.attribute == value]ফিল্টার ফাংশনের অভ্যন্তরে নয় এমন সমস্ত আচরণ পৃষ্ঠের উপরে থাকায় অভিব্যক্তিটি থেকে কী ঘটছে তা আরও স্পষ্ট ।

প্রান্তিক হওয়ায় দুটি পদ্ধতির পারফরম্যান্সের পার্থক্য সম্পর্কে আমি খুব বেশি চিন্তা করব না। আমি যদি সত্যিই এটির আবেদন করতে পারি তবে এটি যদি আপনার অ্যাপ্লিকেশনটিতে অন্তরায় হিসাবে প্রমাণিত হয় তবে এটি কেবলমাত্র অনুকূল হবে।

এছাড়াও যেহেতু BDFL চাচ্ছিল filterভাষা থেকে তারপর নিশ্চয় সর্বস্বান্ত স্বয়ংক্রিয়ভাবে তালিকা comprehensions আরো তোলে Pythonic ;-)



1
তবে হ্রাস করা সহজ সরঞ্জামগুলির সাথে করা সবচেয়ে জটিল complex বোধগম্যতা প্রতিস্থাপনের জন্য মানচিত্র এবং ফিল্টার তুচ্ছ!
njzk2

8
পাইথন 3 এ হ্রাসকে কমিয়ে আনা হয়েছিল জানি না। অন্তর্দৃষ্টি জন্য ধন্যবাদ! হ্রাস () এখনও পাইসপার্কের মতো বিতরণকৃত কম্পিউটারে বেশ সহায়ক। আমি মনে করি এটি একটি ভুল ছিল ..
তাগর

1
@ টাগর আপনি এখনও কমিয়ে ব্যবহার করতে পারবেন আপনাকে এটি কেবল ফান্টুলগুলি থেকে আমদানি করতে হবে
আইসিসি ৯7

69

যেহেতু যে কোনও গতির পার্থক্য হ্রাস করা আবশ্যক, ফিল্টারগুলি ব্যবহার করতে হবে বা বোধগম্য তালিকাটি স্বাদে নেমে আসে কিনা। সাধারণভাবে আমি বোধগম্য ব্যবহার করতে আগ্রহী (যা এখানে বেশিরভাগ উত্তরগুলির সাথে একমত বলে মনে হয়), তবে একটি ক্ষেত্রে রয়েছে যেখানে আমি পছন্দ করি filter

খুব ঘন ঘন ব্যবহারের ক্ষেত্রে হ'ল প্রিডিকেট পি (এক্স) এর সাথে কিছু পুনরাবৃত্তিযোগ্য এক্স এর মানগুলি বের করা হচ্ছে:

[x for x in X if P(x)]

তবে কখনও কখনও আপনি প্রথমে মানগুলিতে কিছু ফাংশন প্রয়োগ করতে চান:

[f(x) for x in X if P(f(x))]


একটি নির্দিষ্ট উদাহরণ হিসাবে, বিবেচনা করুন

primes_cubed = [x*x*x for x in range(1000) if prime(x)]

আমি মনে করি এটি ব্যবহারের চেয়ে কিছুটা ভাল দেখাচ্ছে filter। তবে এখন বিবেচনা করুন

prime_cubes = [x*x*x for x in range(1000) if prime(x*x*x)]

এই ক্ষেত্রে আমরা filterপোস্ট-গণিত মানের বিরুদ্ধে চাই to কিউবকে দু'বার গণনা করার বিষয়টি ছাড়াও (আরও ব্যয়বহুল গণনার কল্পনা করুন), ডিআরওয়াই নান্দনিকতা লঙ্ঘন করে দুবার অভিব্যক্তি লেখার বিষয়টি রয়েছে । এই ক্ষেত্রে আমি ব্যবহার করতে প্রস্তুত হতে হবে

prime_cubes = filter(prime, [x*x*x for x in range(1000)])

7
আপনি অন্য তালিকা বোঝার মাধ্যমে প্রধান ব্যবহার বিবেচনা করবেন না? যেমন[prime(i) for i in [x**3 for x in range(1000)]]
viki.omega9

20
x*x*xএকটি মৌলিক সংখ্যা হতে পারে না, যেমন এটি রয়েছে x^2এবং xএকটি উপাদান হিসাবে, উদাহরণটি গাণিতিক উপায়ে বাস্তবে বোঝায় না, তবে এটি এখনও সহায়ক help (যদিও আমরা আরও ভাল কিছু খুঁজে পেতে পারি?)
জেলফির কাল্টসাহেল

3
নোট করুন যে আমরা মেমরিটি না খেতে চাইলে আমরা শেষ উদাহরণের পরিবর্তে একটি জেনারেটর এক্সপ্রেশন ব্যবহার করতে পারি:prime_cubes = filter(prime, (x*x*x for x in range(1000)))
মতেন উলহাক

4
@ ম্যাটেন উলহাক এটিকে prime_cubes = [1]মেমরি এবং সিপিইউ চক্র উভয়ই বাছাই করতে অনুকূলিত করা যেতে পারে ;-)
ডেনিস ক্রুপেনিক

7
@ ডেনিসক্রুপেনিক বা এর চেয়েও,[]
মাতেন উলহাক

29

যদিও filterএটি "দ্রুততম উপায়" হতে পারে, তবে পারফরম্যান্স একেবারে সমালোচনামূলক না হলে "পাইথোনিক ওয়ে" এ জাতীয় বিষয়গুলির যত্ন নেওয়া উচিত নয় (এই ক্ষেত্রে আপনি পাইথন ব্যবহার করবেন না!)।


9
প্রায়শই দেখা-পাওয়া তর্কটির বিষয়ে দেরিতে মন্তব্য: কখনও কখনও এটি বিশ্লেষণ 10 এর পরিবর্তে 5 ঘন্টার মধ্যে চালানো একটি পার্থক্য তৈরি করে, এবং যদি পাইথন কোডটি অনুকূল করে এক ঘন্টা নিয়ে তা অর্জন করা যায় তবে এটি মূল্যবান হতে পারে (বিশেষত যদি এটি হয় তবে অজগর দিয়ে আরামদায়ক এবং দ্রুত ভাষার সাথে নয়)।
বিলি

তবে আরও গুরুত্বপূর্ণটি হল উত্স কোড এটি পড়ার এবং বুঝতে চেষ্টা করার কারণে আমাদেরকে কতটা ধীর করে দেয়!
thoni56

20

আমি ভেবেছিলাম যে আমি কেবল অজগর 3 এ যুক্ত করব, ফিল্টার () আসলে একটি পুনরাবৃত্ত বস্তু, সুতরাং আপনি ফিল্টার তালিকা তৈরি করতে আপনার ফিল্টার পদ্ধতি কলটি তালিকায় () করতে হবে। তাই অজগর 2:

lst_a = range(25) #arbitrary list
lst_b = [num for num in lst_a if num % 2 == 0]
lst_c = filter(lambda num: num % 2 == 0, lst_a)

তালিকা বি এবং সি একই মান রয়েছে এবং ফিল্টার () সমতুল্য হিসাবে প্রায় একই সময়ে সম্পন্ন হয়েছিল [x এর জন্য x যদি z হয়]। যাইহোক, 3-এ, এই একই কোডটি ফিল্টার তালিকা নয়, একটি ফিল্টার অবজেক্টযুক্ত তালিকা সি ছেড়ে যাবে। 3 এ একই মান উত্পাদন করতে:

lst_a = range(25) #arbitrary list
lst_b = [num for num in lst_a if num % 2 == 0]
lst_c = list(filter(lambda num: num %2 == 0, lst_a))

সমস্যাটি হ'ল তালিকটি () এটির তর্ক হিসাবে পুনরাবৃত্ত হয় এবং সেই যুক্তি থেকে একটি নতুন তালিকা তৈরি করে। ফলাফলটি হল যে পাইথন 3 এ এইভাবে ফিল্টারটি ব্যবহার করতে দ্বিগুণ দীর্ঘ সময় লাগবে [x এর জন্য x জন্য y if z] পদ্ধতির কারণ আপনাকে ফিল্টার () এর পাশাপাশি আউটপুটটি পুনরুক্ত করতে হবে মূল তালিকাটিও।


13

একটি গুরুত্বপূর্ণ পার্থক্য হ'ল তালিকার বোঝাপড়াটি listকিছুক্ষণ ফিরে আসবে যখন ফিল্টারটি একটি দেয় filter, যা আপনি একটির মতো চালিত করতে পারবেন না list(যেমন: lenএটির দিকে কল করুন, যা ফেরতের সাথে কাজ করে না filter)।

আমার নিজের স্ব-শিক্ষার বিষয়টি আমাকে কিছু অনুরূপ ইস্যুতে নিয়ে এসেছিল।

যে হচ্ছে বললেন, ফলে আছে একটি উপায় না থাকলে listA থেকে filterএকটু মত .NET কাজ কী হবে যখন আপনি কি lst.Where(i => i.something()).ToList(), আমি জানি জানতে আগ্রহী নই।

সম্পাদনা: পাইথন 3 এর ক্ষেত্রে এটি 2, নয় 2 (মন্তব্যে আলোচনা দেখুন)।


4
ফিল্টার একটি তালিকা দেয় এবং আমরা এটিতে লেন ব্যবহার করতে পারি। কমপক্ষে আমার পাইথনে ২.7..6।
thiruvenkadam

7
এটা তোলে পাইথন 3 ঘটনা না a = [1, 2, 3, 4, 5, 6, 7, 8] f = filter(lambda x: x % 2 == 0, a) lc = [i for i in a if i % 2 == 0] >>> type(f) <class 'filter'> >>> type(lc) <class 'list'>
Adeynack

3
"যদি ফলাফলের তালিকা থাকার কোনও উপায় থাকে ... আমি এটি জানতে আগ্রহী"। শুধু কল list()ফলাফলে: list(filter(my_func, my_iterable))। এবং অবশ্যই আপনি , বা , বা অন্য যে কোনও পুনরাবৃত্তযোগ্য লাগে তার listসাথে প্রতিস্থাপন করতে পারেন । তবে কার্যকরী প্রোগ্রামার ব্যতীত অন্য কারও কাছে কেস আরও স্পষ্টত রূপান্তর পরিবর্তে তালিকা বোধগম্যতা ব্যবহার করা আরও শক্তিশালী । settuplefilterlist
স্টিভ জেসোপ

10

আমি দ্বিতীয় উপায় আরও পাঠযোগ্য। উদ্দেশ্যটি ঠিক কী তা আপনাকে জানায়: তালিকাটি ফিল্টার করুন।
পিএস: ভেরিয়েবলের নাম হিসাবে 'তালিকা' ব্যবহার করবেন না


7

filterএকটি বিল্টিন ফাংশন ব্যবহার করা হলে সাধারণত কিছুটা দ্রুত হয়।

আমি আশা করি আপনার ক্ষেত্রে তালিকার বোঝাপড়াটি আরও দ্রুত হবে


পাইথন-মি টাইমিট 'ফিল্টার (ল্যাম্বদা এক্স: এক্স [1,2,3,4,5] এ, রেঞ্জ (10000000))' 10 লুপ, 3 লুপ প্রতি পাইপ পাইথন-মি টাইমিট '[এক্স এর জন্য এক্স পরিসীমা (10000000) x যদি [[1,2,3,4,5]] '10 টি লুপে হয়, লুপ প্রতি 3: 860 ম্যাসেকের মধ্যে সেরা না ?!
giaosudau

@ সেপডাউ, ল্যাম্বদা ফাংশনগুলি অন্তর্নির্মিত নয়। তালিকা বোধগম্যতা গত 4 বছরে উন্নত হয়েছে - এখন বিল্টিন ফাংশন সহ এমনকি তফাতটি নগণ্য
জন লা রুই

7

ফিল্টার ঠিক তাই। এটি একটি তালিকার উপাদানগুলিকে ফিল্টার করে। আপনি সংজ্ঞাটি একইভাবে উল্লেখ করতে পারেন (আমি আগে উল্লিখিত অফিসিয়াল ডক্স লিঙ্কে)। অন্যদিকে তালিকার বোঝাপড়াটি এমন কিছু যা পূর্ববর্তী তালিকার কোনও কিছুতে কাজ করার পরে একটি নতুন তালিকা তৈরি করে । (ফিল্টার এবং তালিকা অনুধাবন উভয়ই নতুন তালিকা তৈরি করে এবং পুরানো তালিকার জায়গায় ক্রিয়াকলাপ না করে। , বলুন, সম্পূর্ণ নতুন ডেটা টাইপ string যেমন পূর্ণসংখ্যাকে স্ট্রিংয়ে রূপান্তর করা ইত্যাদি)

আপনার উদাহরণে সংজ্ঞা অনুসারে তালিকা বোঝার চেয়ে ফিল্টার ব্যবহার করা ভাল। তবে, যদি আপনি চান, তালিকার উপাদানগুলি থেকে অন্যান্য_ট্রিবিউট বলুন, আপনার উদাহরণে একটি নতুন তালিকা হিসাবে পুনরুদ্ধার করা উচিত, তবে আপনি তালিকা বোধগম্যতা ব্যবহার করতে পারেন।

return [item.other_attribute for item in my_list if item.attribute==value]

ফিল্টার এবং তালিকা বোঝার সম্পর্কে আমি আসলে এটি মনে করি actually তালিকার মধ্যে কয়েকটি জিনিস সরান এবং অন্যান্য উপাদানগুলি অক্ষত রাখুন, ফিল্টারটি ব্যবহার করুন। উপাদানগুলিতে আপনার নিজের উপর কিছু যুক্তি ব্যবহার করুন এবং কোনও উদ্দেশ্যে উপযুক্ত জলযুক্ত ডাউন তালিকা তৈরি করুন, তালিকা বোধগম্যতা ব্যবহার করুন।


2
ডাউন ভোট দেওয়ার কারণটি জানতে পেরে আমি খুশি হব যাতে ভবিষ্যতে আর কোথাও এর পুনরাবৃত্তি না করব।
তিরুভেঙ্কদম

ফিল্টার এবং তালিকা বোঝার সংজ্ঞা প্রয়োজনীয় ছিল না, কারণ তাদের অর্থ নিয়ে বিতর্ক করা হচ্ছে না। কেবলমাত্র "নতুন" তালিকাগুলির জন্য একটি তালিকা বোধগম্য ব্যবহার করা উচিত তবে এটি যুক্তিযুক্ত নয়।
Agos

আমি সংজ্ঞাটি বলার জন্য ব্যবহার করেছিলাম যে ফিল্টার আপনাকে একই উপাদানগুলির সাথে তালিকা দেয় যা কেসের ক্ষেত্রে সত্য তবে তালিকা বোঝার সাথে আমরা উপাদানগুলিকে নিজেরাই সংশোধন করতে পারি, যেমন ইন্টে স্টে রূপান্তর করার মতো। তবে পয়েন্টটি নেওয়া হয়েছে :-)
থিরুভেনকাদাম

4

তালিকা বোধের পরে যখন আমার কিছুতে ফিল্টার করা দরকার তখন আমি এখানে একটি সংক্ষিপ্ত অংশ ব্যবহার করি । কেবলমাত্র ফিল্টার, ল্যাম্বদা এবং তালিকার সংমিশ্রণ (অন্যথায় একটি বিড়ালের আনুগত্য এবং একটি কুকুরের পরিষ্কারতা হিসাবে পরিচিত) known

এই ক্ষেত্রে আমি একটি ফাইল পড়ছি, ফাঁকা লাইনগুলি আলাদা করে রেখেছি, লাইনে মন্তব্য করেছি, এবং কোনও লাইনে মন্তব্য করার পরে কিছু:

# Throw out blank lines and comments
with open('file.txt', 'r') as lines:        
    # From the inside out:
    #    [s.partition('#')[0].strip() for s in lines]... Throws out comments
    #   filter(lambda x: x!= '', [s.part... Filters out blank lines
    #  y for y in filter... Converts filter object to list
    file_contents = [y for y in filter(lambda x: x != '', [s.partition('#')[0].strip() for s in lines])]

এটি সত্যিই খুব সামান্য কোডে অনেক অর্জন করে। আমি মনে করি সহজেই বোঝার জন্য এটি এক লাইনে কিছুটা যুক্তিযুক্ত হতে পারে এবং পাঠযোগ্যতা যা গণনা করা হয়।
জেলফির কালটস্টল

আপনি এটি হিসাবে লিখতে পারেনfile_contents = list(filter(None, (s.partition('#')[0].strip() for s in lines)))
স্টিভ জেসোপ

4

গৃহীত উত্তর ছাড়াও, একটি কোণার কেস রয়েছে যখন আপনি তালিকা বোধের পরিবর্তে ফিল্টার ব্যবহার করা উচিত। যদি তালিকাটি অপ্রয়োজনীয় হয় তবে আপনি সরাসরি তালিকান বোঝার সাথে এটি প্রক্রিয়া করতে পারবেন না। বাস্তব ব্যবহারকারীর উদাহরণ হ'ল আপনি যদি ব্যবহার করেনpyodbc ডাটাবেস থেকে ফলাফলগুলি পড়তে চান। এর fetchAll()ফলাফলগুলি cursorএকটি অদৃশ্যযোগ্য তালিকা। এই পরিস্থিতিতে, প্রত্যাশিত ফলাফলগুলিতে সরাসরি কারসাজি করতে, ফিল্টারটি ব্যবহার করা উচিত:

cursor.execute("SELECT * FROM TABLE1;")
data_from_db = cursor.fetchall()
processed_data = filter(lambda s: 'abc' in s.field1 or s.StartTime >= start_date_time, data_from_db) 

আপনি যদি এখানে তালিকা উপলব্ধি ব্যবহার করেন তবে ত্রুটিটি পাবেন:

প্রকারের ত্রুটি: অনিবার্য প্রকার: 'তালিকা'


1
সমস্ত তালিকাগুলি অপসারণযোগ্য >>> hash(list()) # TypeError: unhashable type: 'list'দ্বিতীয়ত এটি সূক্ষ্মভাবে কাজ করে:processed_data = [s for s in data_from_db if 'abc' in s.field1 or s.StartTime >= start_date_time]
টমাস

"যদি তালিকাটি অপ্রয়োজনীয় হয় তবে আপনি সরাসরি তালিকা বোঝার সাথে এটি প্রক্রিয়া করতে পারবেন না।" এটি সত্য নয়, এবং সমস্ত তালিকাই যাই হোক না কেন অপসারণযোগ্য।
juanpa.arrivillaga

3

এটা আমার কিছু সময় সঙ্গে familiarized পেতে নেন higher order functions filterএবং map। সুতরাং আমি তাদের filterঅভ্যস্ত হয়ে গিয়েছিলাম এবং আমি প্রকৃতপক্ষে পছন্দ করেছি কারণ এটি স্পষ্ট ছিল যে যা সত্যবাদী তা রাখার মাধ্যমে এটি ফিল্টার করে এবং আমি শীতল অনুভব করেছি যে আমি কিছু functional programmingপদ জানি ।

তারপরে আমি এই উত্তরণটি (ফ্লুয়েন্ট পাইথন বুক) পড়েছি:

পাইথন 3 এ মানচিত্র এবং ফিল্টার ফাংশনগুলি এখনও অন্তর্নির্মিত, তবে যেহেতু তালিকা বোঝার এবং জেনারেটরের এক্স-প্রেসগুলির প্রবর্তন, সেগুলি তেমন গুরুত্বপূর্ণ নয়। একটি লিস্টকম্প বা জিনপ এক্স ম্যাপ এবং ফিল্টার মিলিত কাজ করে তবে আরও পঠনযোগ্য।

এবং এখন আমি ভাবি, কেন filter/ mapযদি আপনি ইতিমধ্যে তালিকা বোধগম্যতার মতো বিস্তৃত আইডিয়ামগুলির সাথে এটি অর্জন করতে পারেন তবে ধারণাটি নিয়ে কেন বিরক্ত হন । তদ্ব্যতীত mapsএবং filtersফাংশন ধরণের। এই ক্ষেত্রে আমি Anonymous functionsল্যাম্বডাস ব্যবহার পছন্দ করি ।

পরিশেষে, কেবল এটি পরীক্ষার জন্য, আমি উভয় পদ্ধতি ( mapএবং listComp) সময়সই করেছি এবং আমি কোনও প্রাসঙ্গিক গতির পার্থক্য দেখতে পাই নি যা সম্পর্কে তর্ক করার পক্ষে ন্যায্যতা প্রমাণ করে।

from timeit import Timer

timeMap = Timer(lambda: list(map(lambda x: x*x, range(10**7))))
print(timeMap.timeit(number=100))

timeListComp = Timer(lambda:[(lambda x: x*x) for x in range(10**7)])
print(timeListComp.timeit(number=100))

#Map:                 166.95695265199174
#List Comprehension   177.97208347299602

0

অদ্ভুতভাবে পাইথন 3-তে, আমি ফিল্টার তালিকা বোধের চেয়ে দ্রুত সম্পাদন করতে দেখছি।

আমি সর্বদা ভাবতাম যে তালিকার বোধগম্যতা আরও পারফরম্যান্ট হবে। এর মতো কিছু: [ব্র্যান্ড_নেমে নামের জন্য নাম_ডিবি যদি নাম না হয় তবে] উত্পন্ন বাইটকোডটি আরও ভাল।

>>> def f1(seq):
...     return list(filter(None, seq))
>>> def f2(seq):
...     return [i for i in seq if i is not None]
>>> disassemble(f1.__code__)
2         0 LOAD_GLOBAL              0 (list)
          2 LOAD_GLOBAL              1 (filter)
          4 LOAD_CONST               0 (None)
          6 LOAD_FAST                0 (seq)
          8 CALL_FUNCTION            2
         10 CALL_FUNCTION            1
         12 RETURN_VALUE
>>> disassemble(f2.__code__)
2           0 LOAD_CONST               1 (<code object <listcomp> at 0x10cfcaa50, file "<stdin>", line 2>)
          2 LOAD_CONST               2 ('f2.<locals>.<listcomp>')
          4 MAKE_FUNCTION            0
          6 LOAD_FAST                0 (seq)
          8 GET_ITER
         10 CALL_FUNCTION            1
         12 RETURN_VALUE

তবে এগুলি আসলে ধীর:

   >>> timeit(stmt="f1(range(1000))", setup="from __main__ import f1,f2")
   21.177661532000116
   >>> timeit(stmt="f2(range(1000))", setup="from __main__ import f1,f2")
   42.233950221000214

8
অবৈধ তুলনা । প্রথমত, আপনি ফিল্টার সংস্করণে ল্যাম্বডা ফাংশনটি পাচ্ছেন না, যা এটি পরিচয় ফাংশনে ডিফল্ট করে তোলে। যখন সংজ্ঞা if not Noneতালিকা ধী আপনি হয় একটি ল্যামডা ফাংশন সংজ্ঞায়িত (লক্ষ্য MAKE_FUNCTIONবিবৃতি)। দ্বিতীয়ত, ফলাফলগুলি পৃথক, কারণ তালিকা অনুধাবন সংস্করণটি কেবলমাত্র Noneমান সরিয়ে ফেলবে , অন্যদিকে ফিল্টার সংস্করণ সমস্ত "মিথ্যা" মানগুলি সরিয়ে ফেলবে। এই কথাটি বলে, মাইক্রোব্যাঙ্কমার্কিংয়ের পুরো উদ্দেশ্যটি অকেজো। এগুলি এক মিলিয়ন পুনরাবৃত্তি, বার 1 কে আইটেম! পার্থক্য নগণ্য
ভিক্টর শ্রদ্ধার

-7

আমার গ্রহণ

def filter_list(list, key, value, limit=None):
    return [i for i in list if i[key] == value][:limit]

3
iকখনও বলা হয় নি যে dict, এবং এর প্রয়োজন নেই limit। এগুলি বাদে ওপি যে পরামর্শ দিয়েছে তার চেয়ে এটি কীভাবে আলাদা এবং এটি প্রশ্নের উত্তর কীভাবে দেয়?
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.