2013-08-30 14 views
26

एक सूची को देखते हुए, क्या पहले गैर-कोई नहीं मान पाने का कोई तरीका है? और, यदि हां, तो ऐसा करने के लिए पाइथोनिक तरीका क्या होगा?सूची से पहले गैर-कोई भी मूल्य प्राप्त नहीं करना

उदाहरण के लिए, मेरे पास है:

  • a = objA.addreses.country.code
  • b = objB.country.code
  • c = None
  • d = 'CA'

इस मामले में, अगर एक कोई नहीं है, तो मैं प्राप्त करना चाहते हैं ख। यदि ए और बी दोनों कोई नहीं हैं, तो मैं डी प्राप्त करना चाहता हूं।

वर्तमान में मैं (((a or b) or c) or d) की लाइनों के साथ कुछ कर रहा हूं, क्या कोई और तरीका है?

उत्तर

62

आप next() उपयोग कर सकते हैं: इस सूची में केवल Nones शामिल

>>> a = [None, None, None, 1, 2, 3, 4, 5] 
>>> next(item for item in a if item is not None) 
1 

है, यह StopIteration अपवाद फेंक देते हैं। आप इस मामले में कोई डिफ़ॉल्ट मान चाहते हैं, ऐसा करते हैं:

>>> a = [None, None, None] 
>>> next((item for item in a if item is not None), 'All are Nones') 
All are Nones 
+3

मैं केवल एक ही आइटम वाले सूचियों को संभालने के लिए 'रोकथाम' को छोड़कर 'प्रयास करें' 'जोड़ता हूं। लेकिन यह एक अच्छा जवाब है। – Germano

+1

@Germano ने उत्तर को अपडेट किया, कृपया जांचें। बीटीडब्ल्यू, जॉन का जवाब स्वीकार किया जाना चाहिए - वह सबसे पहले केवल किसी भी सूची के लिए समाधान का सुझाव देने वाला था। – alecxe

+0

असल में मुझे लगता है कि जॉन का जवाब सही नहीं है: यह केवल 'सही' या 'गलत' लौटाता है, न कि सूची का पहला 'आइटम' आइटम नहीं। – Germano

4

से निम्नलिखित (आप एक लाइनर यह अगर तुम चाहते थे सकता है) ग्रहण करें:

values = (a, b, c, d) 
not_None = (el for el in values if el is not None) 
value = next(not_None, None) 

यह पहली गैर लेता है None मूल्य, या इसके बजाय None देता है।

+0

मुझे समझ में नहीं आता है। क्या यह सिर्फ 'सही' या 'गलत' प्रिंट नहीं करेगा? – thefourtheye

+0

@thefourtheye हां - एक मस्तिष्क burp था ... इसे इंगित करने के लिए धन्यवाद –

2

first_true एक itertools नुस्खा Python 3 docs में पाया जाता है:

def first_true(iterable, default=False, pred=None): 
    """Returns the first true value in the iterable. 

    If no true value is found, returns *default* 

    If *pred* is not None, returns the first item 
    for which pred(item) is true. 

    """ 
    # first_true([a,b,c], x) --> a or b or c or x 
    # first_true([a,b], x, f) --> a if f(a) else b if f(b) else x 
    return next(filter(pred, iterable), default) 

एक उत्तरार्द्ध नुस्खा एक पुस्तकालय लागू करने या more_itertools आयात करने के लिए चुन सकते हैं, कि itertools व्यंजनों और अधिक के साथ जहाजों:

> pip install more_itertools 

उपयोग करें:

import more_itertools as mit 

a = [None, None, None, 1, 2, 3, 4, 5] 
mit.first_true(a, pred=lambda x: x is not None) 
# 1 

a = [None, None, None] 
mit.first_true(a, default="All are None", pred=lambda x: x is not None) 
# 'All are None' 

भविष्यवाणी का उपयोग क्यों करें?

"पहला गैर- None" आइटम "पहले True" आइटम जैसा नहीं है, उदा। [None, None, 0] जहां 0 पहला गैर- None है, लेकिन यह पहला True आइटम नहीं है। भविष्यवाणी first_true उपयोग करने योग्य होने के लिए अनुमति देता है, किसी भी पहले देखा गया, गैर-कोई नहीं, पुनरावर्तक में झूठी वस्तु को सुनिश्चित करने के लिए अभी भी वापस आ गया है (उदा। 0, False) डिफ़ॉल्ट के बजाय।

a = [None, None, None, False] 
mit.first_true(a, default="All are None", pred=lambda x: x is not None) 
# 'False' 
संबंधित मुद्दे