তালিকার সমস্ত উপাদান শর্তের সাথে মেলে কিনা তা কীভাবে পরীক্ষা করবেন?


208

আমার 20000 টির মতো তালিকা সমন্বিত একটি তালিকা রয়েছে have আমি প্রতিটি তালিকার তৃতীয় উপাদানটিকে পতাকা হিসাবে ব্যবহার করি। আমি এই তালিকায় কিছু অপারেশন করতে চাই যতক্ষণ না কমপক্ষে একটি উপাদানের পতাকা 0 হয়, এটি এর মতো:

my_list = [["a", "b", 0], ["c", "d", 0], ["e", "f", 0], .....]

শুরুতে, সমস্ত পতাকা 0 হয় at কমপক্ষে একটি উপাদানটির পতাকা 0 আছে কিনা তা পরীক্ষা করতে আমি কিছুক্ষণ লুপ ব্যবহার করি use

def check(list_):
    for item in list_:
        if item[2] == 0:
            return True
    return False

যদি check(my_list)ফিরে আসে Trueতবে আমি আমার তালিকায় কাজ চালিয়ে যাব:

while check(my_list):
    for item in my_list:
        if condition:
            item[2] = 1
        else:
            do_sth()

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

আসল মাই_লিস্টে পতাকা নেই:

my_list = [["a", "b"], ["c", "d"], ["e", "f"], .....]

যেহেতু আমি এটিগুলি পুনরাবৃত্তি করার সাথে সাথে উপাদানগুলি সরাতে পারিনি, তাই আমি এই পতাকাগুলি আবিষ্কার করেছি। তবে my_listএতে অনেকগুলি আইটেম রয়েছে এবং whileপ্রতিটি forলুপে লুপগুলি সমস্ত পড়ে এবং এতে প্রচুর সময় ব্যয় হয়! আপনার কি কোন পরামর্শ আছে?


3
দেখে মনে হচ্ছে আপনার সমস্যার জন্য ডেটা কাঠামো আদর্শ নয়। আপনি যদি প্রসঙ্গটি আরও কিছুটা ব্যাখ্যা করেন তবে আমরা আরও উপযুক্ত কিছু প্রস্তাব করতে পারি।
uselpa

হতে পারে আপনি আইটেমগুলি অপসারণের পরিবর্তে তালিকার সাথে পুনরাবৃত্তি করতে Noneবা []এটিকে প্রতিস্থাপন করতে পারেন । অভ্যন্তরীণ লুপের প্রতিটি পাসের আগে সমস্ত আইটেমটি পুনরুদ্ধার করে 'চেক () with দিয়ে পুরো তালিকাটি পরীক্ষা করা খুব ধীর পদ্ধতির।
মার্টিনিউ

উত্তর:


402

এখানে সর্বোত্তম উত্তরটি হ'ল ব্যবহার করা all(), যা এই পরিস্থিতির জন্য অন্তর্নির্মিত। আপনি পরিচ্ছন্ন এবং দক্ষতার সাথে ফলাফলটি তৈরি করতে আমরা এটি একটি জেনারেটর এক্সপ্রেশনের সাথে একত্রিত করি । উদাহরণ স্বরূপ:

>>> items = [[1, 2, 0], [1, 2, 0], [1, 2, 0]]
>>> all(flag == 0 for (_, _, flag) in items)
True
>>> items = [[1, 2, 0], [1, 2, 1], [1, 2, 0]]
>>> all(flag == 0 for (_, _, flag) in items)
False

দ্রষ্টব্য যে all(flag == 0 for (_, _, flag) in items)সরাসরি এর সমতুল্য all(item[2] == 0 for item in items), এই ক্ষেত্রে পড়ার জন্য এটি কেবলমাত্র খুব ভাল।

এবং, ফিল্টার উদাহরণের জন্য, একটি তালিকা বোঝাপড়া (অবশ্যই আপনি উপযুক্ত যেখানে একটি জেনারেটর এক্সপ্রেশন ব্যবহার করতে পারেন):

>>> [x for x in items if x[2] == 0]
[[1, 2, 0], [1, 2, 0]]

যদি আপনি কমপক্ষে একটি উপাদান 0 হয় তা পরীক্ষা করতে চান তবে আরও ভাল বিকল্পটি ব্যবহার করা any()যা আরও পঠনযোগ্য:

>>> any(flag == 0 for (_, _, flag) in items)
True

ল্যাম্বডা ব্যবহারে আমার দোষ, পাইথনের সকলেই হাস্কেল এটের মতো প্রথম যুক্তি হিসাবে কোনও ফাংশন গ্রহণ করে না। আল। :)
হ্যাম্পাস নীলসন

3
@ হ্যাম্পাসনিলসন জেনারেটর এক্সপ্রেশন হিসাবে একটি তালিকা বোধগম্য নয়। হিসাবে all()এবং any()শর্ট সার্কিট, যদি, উদাহরণস্বরূপ, খনি উপর প্রথম মান মূল্যায়ন করে False, all()ব্যর্থ হবে এবং কোন আরো মান চেক করবেন, ফেরার False। আপনার উদাহরণটি একই কাজ করবে, ব্যতীত এটি প্রথমে তুলনাগুলির সম্পূর্ণ তালিকা তৈরি করবে, অর্থাত কিছুই করার জন্য অনেকগুলি প্রক্রিয়াজাতকরণ।
গ্যারেথ লেটি

14

আপনি যদি তালিকার কোনও আইটেম একটি শর্ত ব্যবহার লঙ্ঘন করে কিনা তা পরীক্ষা করতে চান all:

if all([x[2] == 0 for x in lista]):
    # Will run if all elements in the list has x[2] = 0 (use not to invert if necessary)

মিলছে না এমন সমস্ত উপাদান মুছে ফেলতে, ব্যবহার করুন filter

# Will remove all elements where x[2] is 0
listb = filter(lambda x: x[2] != 0, listb)

2
আপনি অপসারণ করতে পারেন [...]মধ্যে all(...)যেহেতু এটি তারপর একটি তালিকা, যা না শুধুমাত্র আপনি দুটি অক্ষর সংরক্ষণ পরিবর্তে একটি জেনারেটর তৈরি করতে পারেন কিন্তু মেমরি এবং সময় বাঁচায়। জেনারেটর ব্যবহার করে, একসাথে কেবলমাত্র একটি আইটেম গণনা করা হবে (পূর্ববর্তী ফলাফলগুলি আর ব্যবহার না করা থেকে বাদ দেওয়া হবে) এবং যদি তাদের মধ্যে কোনওটি বেরিয়ে আসে False, তবে জেনারেটর বাকী গণনা বন্ধ করে দেবে।
ইনকিউ

7

আপনি এরটুলসের সংক্ষিপ্তসারটি এভাবে ব্যবহার করতে পারেন, কোনও শর্ত পূরণ হওয়ার পরে এটি বন্ধ হয়ে যাবে যা আপনার বক্তব্যকে ব্যর্থ করে। বিপরীত পদ্ধতিটি ড্রপফুল হবে

for x in itertools.takewhile(lambda x: x[2] == 0, list)
    print x

0

ব্যবহারের অন্য উপায় itertools.ifilter। এটি সত্যতা এবং প্রক্রিয়া পরীক্ষা করে (ব্যবহার করে lambda)

Sample-

for x in itertools.ifilter(lambda x: x[2] == 0, my_list):
    print x

0

এই উপায়টি ব্যবহারের চেয়ে কিছুটা নমনীয় all():

my_list = [[1, 2, 0], [1, 2, 0], [1, 2, 0]]
all_zeros = False if False in [x[2] == 0 for x in my_list] else True
any_zeros = True if True in [x[2] == 0 for x in my_list] else False

বা আরও সংক্ষেপে:

all_zeros = not False in [x[2] == 0 for x in my_list]
any_zeros = 0 in [x[2] for x in my_list]

আপনি কেবল বলতে পারেন না all_zeros = False in [x[2] == 0 for x in my_list]এমনকি এমনকি 0 in [x[2] for x in my_list]অনুরূপ জন্য any_zeros? আমি সত্যিই কোন লক্ষণীয় উন্নতি দেখতে পাচ্ছি না all()
ট্রিপলি

না, আপনার সংস্করণ - all_zeros = False in [x[2] == 0 for x in my_list]মূল্যায়ণ করতে Falseআমার মূল্যায়ণ যখন True। আপনি যদি এটিতে পরিবর্তন করেন all_zeros = not (False in [x[2] == 0 for x in my_list])তবে এটি আমার সমতুল্য। এবং 0 in [x[2] for x in my_list]স্পষ্টতই শুধুমাত্র কাজ করতে যাচ্ছে any_zeros। তবে আমি আপনার ধারণার সংক্ষিপ্ততার মতোই, তাই আমি আমার উত্তরটি আপডেট করব
মুল্লহাউসন
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.