2009-10-20 15 views
9

वहाँ जांच करने के लिए एक pythonic तरीका अगर एक सूची (एक नेस्टेड तत्वों & सूचियों के साथ सूची) अनिवार्य रूप से खाली है है? यहां खाली से मेरा मतलब यह है कि सूची में तत्व हो सकते हैं, लेकिन वे खाली सूचियां भी हैं।पायथन: कैसे जांचें कि नेस्टेड सूची अनिवार्य रूप से खाली है या नहीं?

alist = [] 
if not alist: 
    print("Empty list!") 

उदाहरण के लिए, सभी निम्न सूची खालीपन के लिए सकारात्मक होना चाहिए:

alist = [] 
blist = [alist]    # [[]] 
clist = [alist, alist, alist] # [[], [], []] 
dlist = [blist]    # [[[]]] 

उत्तर

8

मैं निम्नलिखित समाधान के लिए फार्म Stephan202 द्वारा चींटियों आसमा और all(map()) द्वारा isinstance() के उपयोग के संयुक्त है। all([])True देता है और फ़ंक्शन इस व्यवहार पर निर्भर करता है। मुझे लगता है कि यह दोनों में से सर्वश्रेष्ठ है और बेहतर है क्योंकि यह TypeError अपवाद पर भरोसा नहीं करता है।

def isListEmpty(inList): 
    if isinstance(inList, list): # Is a list 
     return all(map(isListEmpty, inList)) 
    return False # Not a list 
+2

'सभी को वापस लौटें (नक्शा (isListEmpty, inList)) यदि इंस्टेंसेंस (इनलिस्ट, सूची) और गलत है ':) – Stephan202

+0

स्टीफन 202: हाँ, जो इसे वास्तविक एक-लाइनर में बदल देता है! मैं बस इस पायथन सशर्त अभिव्यक्ति के साथ आरामदायक नहीं हूँ। थोड़ा उलझन में क्योंकि इसे सी टर्नरी ऑपरेटर के रूप में आदेशित नहीं किया जाता है ;-) –

4

मैं नहीं

एक खाली सूची की जांच करने के pythonic तरीका केवल एक फ्लैट सूची पर काम करता है लगता है कि पाइथन में ऐसा करने का एक स्पष्ट तरीका है। कि यह असीम पुनरावर्ती सूची (उदाहरण के लिए, a = []; a.append(a) के लिए) को संभाल नहीं होगा

def empty(li): 
    if li == []: 
     return True 
    else: 
     return all((isinstance(sli, list) and empty(sli)) for sli in li) 

ध्यान दें कि all केवल अजगर> = 2.5 के साथ आता है, और: मेरा सर्वोत्तम अनुमान इस तरह एक पुनरावर्ती समारोह का उपयोग करने के लिए होगा।

+1

अच्छा, मैंने कभी पाइथन में अनंत रिकर्सिव सूचियों के बारे में सोचा नहीं है।यह देखने के लिए अच्छा है कि उन्हें मुद्रित भी किया जा सकता है ;-) –

+0

infinte रिकर्सिव सूचियों के लिए +1। अब [इस सवाल] पर जाएं (http://stackoverflow.com/q/7674685/188595) उनके बारे में पढ़ें। –

1

एक साधारण पुनरावर्ती जांच पर्याप्त होगा, और जितनी जल्दी हो सके वापस जाने के लिए, हम यह मान इनपुट एक सूची नहीं है या गैर सूचियों यह खाली नहीं है

def isEmpty(alist): 
    try: 
     for a in alist: 
      if not isEmpty(a): 
       return False 
    except: 
     # we will reach here if alist is not a iterator/list 
     return False 

    return True 

alist = [] 
blist = [alist]    # [[]] 
clist = [alist, alist, alist] # [[], [], []] 
dlist = [blist]    # [[[]]] 
elist = [1, isEmpty, dlist] 

if isEmpty(alist): 
    print "alist is empty" 

if isEmpty(dlist): 
    print "dlist is empty" 

if not isEmpty(elist): 
    print "elist is not empty" 

आप आगे जांच करने के लिए यह सुधार कर सकते हैं शामिल पुनरावर्ती सूची या कोई सूची वस्तुओं के लिए, या खाली dicts आदि

+2

'isEmpty ([1]) 'विफल रहता है, यह एक समस्या है (यह एक खाली सूची की जांच करने के लिए वास्तव में उपयोगी नहीं है अगर यह केवल उन सूचियों के साथ काम करता है जिन्हें आप खाली होने के बारे में जानते हैं)। –

+0

यह जांचने के लिए एक अच्छा तर्क हो सकता है कि सूची खाली नहीं है :) –

+0

डेलरोथ: अनुराग ने अब जिस समस्या पर टिप्पणी की है उसे ठीक कर दिया है। –

7

सरल कोड, किसी भी iterable वस्तु के लिए काम करता है हो सकता है, न सिर्फ सूचीबद्ध करता है:

>>> def empty(seq): 
...  try: 
...   return all(map(empty, seq)) 
...  except TypeError: 
...   return False 
... 
>>> empty([]) 
True 
>>> empty([4]) 
False 
>>> empty([[]]) 
True 
>>> empty([[], []]) 
True 
>>> empty([[], [8]]) 
False 
>>> empty([[], (False for _ in range(0))]) 
True 
>>> empty([[], (False for _ in range(1))]) 
False 
>>> empty([[], (True for _ in range(1))]) 
False 

इस कोड के रूप में बनाता है समेकन कि जो कुछ भी पुनरावृत्त किया जा सकता है, इसमें अन्य तत्व होंगे, और इसे "पेड़" में एक पत्ता नहीं माना जाना चाहिए। यदि किसी ऑब्जेक्ट पर पुनरावृत्ति करने का प्रयास विफल रहता है, तो यह अनुक्रम नहीं है, और इसलिए निश्चित रूप से खाली अनुक्रम नहीं है (इस प्रकार False वापस आ गया है)। अंत में, यह कोड इस तथ्य का उपयोग करता है कि allTrue देता है यदि इसका तर्क खाली अनुक्रम है।

+2

सभी अपवादों को पकड़ना एक बुरी चीज है जो कोड में वास्तविक त्रुटियों को छिपाने का कारण बन सकती है। –

+1

@ डेनिस: एक मान्य बिंदु। अब इसे 'टाइप एरर' तक सीमित कर दिया गया है। – Stephan202

+2

+1 लेकिन मुझे लगता है कि पाइथन में 'map' का उपयोग नहीं किया जाना चाहिए। 'सभी (खाली) x में x के लिए खाली) 'मुझे बहुत अच्छा लगता है ;-) –

9

आप सूची के माध्यम से पुनरावृति करने की जरूरत नहीं है, सरल बेहतर है, इसलिए कुछ इस तरह काम करेगा:

def empty_tree(input_list): 
    """Recursively iterate through values in nested lists.""" 
    for item in input_list: 
     if not isinstance(item, list) or not empty_tree(item): 
      return False 
    return True 

हालांकि, यह पुनरावर्ती यात्रा है कि आप सबसे शायद पुन: उपयोग होगा अलग करने के लिए अच्छा होगा कहीं और जांच कर रहा है कि यह कोई तत्व नहीं देता है। इस तरह यदि पुनरावृत्ति के तंत्र में परिवर्तन होता है तो आपको एक स्थान में परिवर्तन को लागू करने की आवश्यकता होती है। उदाहरण के लिए जब आपको मनमाने ढंग से नेस्टेड पुनरावृत्तियों, या नेस्टेड डाइक का समर्थन करने की आवश्यकता होती है।

def flatten(input_list): 
    """Recursively iterate through values in nested lists.""" 
    for item in input_list: 
     if isinstance(item, list): # Use what ever nesting condition you need here 
      for child_item in flatten(item): 
       yield child_item 
     else: 
      yield item 

def has_items(seq): 
    """Checks if an iterator has any items.""" 
    return any(1 for _ in seq) 

if not has_items(flatten(my_list)): 
    pass 
+0

चींट्स असमा: मुझे आपके समाधान की सादगी पसंद है! मैंने आपका जवाब संपादित कर लिया है और सरल समाधान को स्थानांतरित कर दिया है। धन्यवाद! :-) –

+0

धन्यवाद, आपने मुझे बहुत समय खोजा है .. अन्य सभी दृष्टिकोण आपके अलावा मेरे लिए काम नहीं करते हैं .. थैक्स –

संबंधित मुद्दे