2012-05-19 14 views
97

मेरी एक सूची है जिसमें 20000 सूचियां शामिल हैं। मैं प्रत्येक सूची के तीसरे तत्व को ध्वज के रूप में उपयोग करता हूं। मैं इस सूची में कुछ कार्यों में करना चाहते हैं जब तक कम से कम एक तत्व के झंडे 0 है, यह की तरह है:कैसे जांचें कि किसी सूची के सभी तत्व किसी शर्त से मेल खाते हैं या नहीं?

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

शुरुआत में सभी झंडे 0. मैं जाँच करने के लिए थोड़ी देर के पाश का उपयोग कर रहे हैं, तो कम से कम एक तत्व की झंडा 0 है:

def check(lista): 
    for item in lista: 
     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 में तत्व को दूर करने के लिए चाहते थे के रूप में मैं दोहराया इसके ऊपर, लेकिन मुझे आइटम को हटाने की अनुमति नहीं है क्योंकि मैं इसे फिर से चालू करता हूं।

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

के रूप में मैं दोहराया इस पर, मैं इन झंडे का आविष्कार के बाद से मैं तत्वों को नहीं निकाल सका:

मूल my_list झंडे नहीं था। लेकिन my_list में कई आइटम हैं, और while लूप प्रत्येक for लूप पर उन सभी को पढ़ता है, और यह बहुत समय लगता है! क्या तुम्हारे पास कोई सुझाव है?

+2

ऐसा लगता है कि अपने डेटा संरचना आपकी समस्या के लिए आदर्श नहीं है।यदि आपने संदर्भ को थोड़ा और समझाया है तो शायद हम कुछ और उचित सुझाव दे सकते हैं। – uselpa

+0

हो सकता है कि आप आइटम को 'कोई नहीं' या '[]' के साथ प्रतिस्थापित कर सकें क्योंकि आप उन्हें हटाने के बजाय सूची में पुन: प्रयास करते हैं। आंतरिक लूप पर प्रत्येक पास से पहले सभी वस्तुओं पर 'चेक() 'पुनरावृत्ति के साथ पूरी सूची की जांच करना बहुत धीमा दृष्टिकोण है। – martineau

उत्तर

211

यहां सबसे अच्छा जवाब all() का उपयोग करना है, जो इस स्थिति के लिए अंतर्निहित है। हम इसे generator expression के साथ गठबंधन करते हैं जिससे आप साफ और कुशलता से परिणाम प्राप्त कर सकें। उदाहरण के लिए:

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

और, उसके फिल्टर उदाहरण के लिए, एक सूची समझ:

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

आप जाँच करना चाहते हैं कम से कम एक तत्व है, 0 है बेहतर विकल्प any() जो अधिक है उपयोग करने के लिए है पठनीय:

>>> any(item[2] == 0 for item in items) 
True 
+0

लैम्ब्डा के उपयोग पर मेरी गलती, पाइथन के सभी कार्यों को हास्केल एट जैसे पहले तर्क के रूप में स्वीकार नहीं करते हैं। अल।, मैंने अपना जवाब एक सूची समझ में बदल दिया। :) –

+2

@ हैम्पस नीलसन एक सूची समझ जनरेटर अभिव्यक्ति के समान नहीं है। 'सभी()' और 'किसी भी() 'शॉर्ट सर्किट के रूप में, उदाहरण के लिए, मेरा पहला मूल्य' गलत 'का मूल्यांकन करता है,' सभी()' असफल हो जाएंगे और 'गलत' लौटने पर और अधिक मूल्यों की जांच नहीं करेंगे। आपका उदाहरण वही करेगा, सिवाय इसके कि यह पहले तुलना की पूरी सूची उत्पन्न करेगा, जिसका मतलब कुछ भी नहीं है। –

5

आप इस तरह की चीज के उपयोग के दौरान उपयोग कर सकते हैं, एक बार शर्त समाप्त होने के बाद यह बंद हो जाएगा जो आपके कथन को विफल कर देता है। विपरीत विधि dropwhile

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

होगा आप सूची में किसी भी आइटम एक शर्त उपयोग 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) 
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 
0

itertools.ifilter का उपयोग करने का एक और तरीका। यह जाँच करता है truthiness और इस प्रक्रिया (lambda का प्रयोग करके)

Sample-

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