0 मान को निकाले बिना किसी सूची से कोई भी मान न निकालें


244

यह मेरा स्रोत था जिसकी मैंने शुरुआत की थी।

मेरी सूची

L = [0, 23, 234, 89, None, 0, 35, 9]

जब मैं इसे चलाता हूं:

L = filter(None, L)

मुझे यह परिणाम मिले

[23, 234, 89, 35, 9]

लेकिन यह वह नहीं है जिसकी मुझे आवश्यकता है, मुझे वास्तव में क्या चाहिए:

[0, 23, 234, 89, 0, 35, 9]

क्योंकि मैं डेटा के प्रतिशत की गणना कर रहा हूं और 0 से बहुत फर्क पड़ता है।

0 मान को हटाए बिना किसी सूची से कोई भी मान कैसे निकालें?

जवाबों:


354
>>> L = [0, 23, 234, 89, None, 0, 35, 9]
>>> [x for x in L if x is not None]
[0, 23, 234, 89, 0, 35, 9]

बस मज़े के लिए, यहाँ है कि आप इसका उपयोग कैसे कर सकते हैं filterबिना lambda(मैं इस कोड की सिफारिश नहीं करूंगा - यह सिर्फ वैज्ञानिक उद्देश्यों के लिए है)

>>> from operator import is_not
>>> from functools import partial
>>> L = [0, 23, 234, 89, None, 0, 35, 9]
>>> filter(partial(is_not, None), L)
[0, 23, 234, 89, 0, 35, 9]

23
कम सुरुचिपूर्ण filterसंस्करण: filter(lambda x: x is not None, L)- आप lambdaउपयोग से छुटकारा पा सकते हैं partialऔर operator.is_notमुझे लगता है, लेकिन यह संभवतः इसके लायक नहीं है क्योंकि सूची-COMP इतना क्लीनर है।
mgilson

3
@mgilson ओह वाह मुझे भी नहीं पता is_notथा कि अस्तित्व में है! मुझे लगता है कि यह केवल था is_, मुझे लगता है कि सिर्फ मनोरंजन के लिए जोड़ रहा हूँ
jamylak

@ जमालिक - हाँ। यह वास्तव में मुझे परेशान करता है जो is_notमौजूद है और मौजूद not_inनहीं है। मुझे वास्तव में लगता है कि not_inइसे एक जादू की विधि में बदल दिया जाना चाहिए __not_contains__... एक प्रश्न देखें जो मैंने कुछ समय पहले पूछा था और एक टिप्पणी जो मैंने एक उत्तरदाता को दी थी ... और अभी भी ऐसा महसूस नहीं होता है कि यह हल हो गया है।
mgilson

@mgilson मुझे लगता है कि उसी धारणा के तहत मैंने यह मान लिया कि यह अस्तित्व में नहीं है। मुझे लगता है कि आप filterfalseउपयोग के मामले पर निर्भर करता है या कुछ का उपयोग कर सकते हैं
जामिलक

@ जमालिक - हाँ। मेरा मुख्य समस्या यह है कि है x > yमतलब यह नहीं है not x <= yक्योंकि आप में कुछ भी कर सकते अजगर में __lt__और __le__, तो क्यों चाहिए x not in yमतलब not x in y(विशेष रूप से not inअपने आप बाईटकोड है?)
mgilson

136

FWIW, पायथन 3 इस समस्या को आसान बनाता है:

>>> L = [0, 23, 234, 89, None, 0, 35, 9]
>>> list(filter(None.__ne__, L))
[0, 23, 234, 89, 0, 35, 9]

पायथन 2 में, आप इसके बजाय सूची बोध का उपयोग करेंगे:

>>> [x for x in L if x is not None]
[0, 23, 234, 89, 0, 35, 9]

+1 क्या आप __ne__उस तरह के उपयोग की सलाह देते हैं , जिसके विपरीत partialऔर ne?
जामिलक

1
@ जमैलाक हां, यह तेज है, लिखने में थोड़ा आसान है, और थोड़ा अधिक स्पष्ट है।
रेमंड हेटिंगर

operatorमॉड्यूल का उपयोग करने पर विचार करें ।
दायां गुना

12
क्या है __ne__?
DrMcCleod

11
@DrMcCleod एक्सप्रेशन को x != yआंतरिक रूप से कहते हैं x.__ne__(y)जहां ne "न के बराबर" है। तो, None.__ne__एक बाध्य विधि है कि रिटर्न है यह सच है जब किसी भी अन्य की तुलना में मूल्य के साथ कहा जाता है कोई नहीं । उदाहरण के लिए, रिटर्न के bm = None.__ne__साथ बुलाया NotImplemented जो सही मूल्य के रूप में है, और गलत रिटर्न देता है । bm(10)bm(None)
रेमंड हेटिंगर

17

सूची की समझ का उपयोग इस प्रकार किया जा सकता है:

l = [i for i in my_list if i is not None]

एल का मूल्य है:

[0, 23, 234, 89, 0, 35, 9]

यह समाधान पहले से ही शीर्ष उत्तर में पाया जाता है, या क्या मुझे कुछ याद आ रहा है?
कासवेद

16

पायथन 2.7 के लिए (पायथन 3 समकक्ष के लिए रेमंड का जवाब देखें):

यह जानना चाहते हैं कि क्या "कुछ भी नहीं है" अजगर (और अन्य ओओ भाषाओं) में इतना सामान्य है, कि मेरे कॉमनडोम में (जो कि मैं "सामान्य आयात" से प्रत्येक मॉड्यूल को आयात करता हूं), मैं इन पंक्तियों को शामिल करता हूं:

def exists(it):
    return (it is not None)

फिर किसी सूची से किसी भी तत्व को निकालने के लिए, बस करें:

filter(exists, L)

मुझे यह पढ़ने में आसान लगता है, इसी सूची बोध की तुलना में (जो रेमंड दिखाता है, उसके पायथन 2 संस्करण के रूप में)।


मैं पायथन 3 के लिए रेमंड्स समाधान पसंद करूंगा, और फिर पायथन 2 के लिए सूची समझ। लेकिन अगर मुझे इस मार्ग पर जाना पड़ा, तो मैं partial(is_not, None)इस समाधान के बजाय । मेरा मानना ​​है कि यह धीमा होगा (हालांकि यह बहुत महत्वपूर्ण नहीं है)। लेकिन अजगर मॉड्यूल के आयात के एक जोड़े के साथ, इस मामले में एक कस्टम परिभाषित समारोह के लिए कोई ज़रूरत नहीं है
जमैका

12

@jamylak का उत्तर काफी अच्छा है, हालाँकि यदि आप इस सरल कार्य को करने के लिए मॉड्यूल के एक जोड़े को आयात नहीं करना चाहते हैं, तो अपना स्वयं का lambdaइन-प्लेस लिखें :

>>> L = [0, 23, 234, 89, None, 0, 35, 9]
>>> filter(lambda v: v is not None, L)
[0, 23, 234, 89, 0, 35, 9]

आपने स्पष्ट रूप से मेरे समाधान को सही ढंग से नहीं पढ़ा था जो [x for x in L if x is not None]कि अन्य कोड था, इसके अलावा मैंने स्पष्ट रूप से कहा था कि मैं सिफारिश नहीं
करूंगा

1
@jamylak - मैंने इसे पढ़ा था, लेकिन आपने इस समाधान को शामिल नहीं किया था। - यह भी सुनिश्चित न करें कि आप 4-5 साल पहले से लोगों के उत्तरों का संपादन क्यों कर रहे हैं।
एटी

5

Iteration vs Space , उपयोग एक मुद्दा हो सकता है। विभिन्न स्थितियों में प्रोफाइलिंग या तो "तेज" हो सकती है और / या "कम मेमोरी" गहन हो सकती है।

# first
>>> L = [0, 23, 234, 89, None, 0, 35, 9, ...]
>>> [x for x in L if x is not None]
[0, 23, 234, 89, 0, 35, 9, ...]

# second
>>> L = [0, 23, 234, 89, None, 0, 35, 9]
>>> for i in range(L.count(None)): L.remove(None)
[0, 23, 234, 89, 0, 35, 9, ...]

पहले दृष्टिकोण (के रूप में भी ने सुझाव दिया @jamylak , @Raymond Hettinger , और @Dipto ), स्मृति में एक डुप्लिकेट सूची जो कुछ के साथ एक बड़ी सूची के लिए महंगा हो सकता है बनाता है Noneप्रविष्टियों।

दूसरा दृष्टिकोण सूची के माध्यम से एक बार चला जाता है, और उसके बाद फिर एक जब तक हर बार Noneपहुँच जाता है। यह कम मेमोरी इंटेंसिव हो सकता है, और यह सूची में जाते ही छोटा हो जाएगा। सूची आकार में कमी Noneसे सामने की बहुत सारी प्रविष्टियों के लिए गति हो सकती है , लेकिन सबसे खराब स्थिति यह होगी कि बहुत सारी Noneप्रविष्टियाँ पीछे थीं।

समानांतरकरण और इन-प्लेस तकनीक अन्य दृष्टिकोण हैं, लेकिन पायथन में प्रत्येक की अपनी जटिलताएं हैं। डेटा और रनटाइम उपयोग-मामलों को जानने के साथ-साथ प्रोग्राम को प्रोफाइल करना गहन संचालन या बड़े डेटा के लिए शुरू करना है।

या तो दृष्टिकोण का चयन करना शायद आम स्थितियों में मायने नहीं रखेगा। यह अंकन की एक प्राथमिकता के रूप में अधिक हो जाता है। वास्तव में, उन असामान्य परिस्थितियों में, numpyया cythonमाइक्रोमैनज पायथन ऑप्टिमाइज़ेशन के प्रयास के बजाय सार्थक विकल्प हो सकते हैं।


इसका बिल्कुल भी प्रशंसक नहीं है, इस समाधान के साथ आप जो पूरा दावा करते हैं, वह यह है कि सूची इतनी बड़ी हो सकती है कि स्मृति में डुप्लीकेट सूची बनाना महंगा हो सकता है। तो फिर आपका समाधान और भी अधिक महंगा हो जाएगा क्योंकि आप पूरी सूची को स्कैन कर रहे हैं L.count(None)और फिर आप .remove(None)कई बार कॉल कर रहे हैं जिससे यह O(N^2)स्थिति होती है जिसे आप हल करने की कोशिश कर रहे हैं, इस तरह से निपटा नहीं जाना चाहिए, डेटा का पुनर्गठन किया जाना चाहिए एक डेटाबेस या फ़ाइल में बजाय अगर यह है कि स्मृति गहन है।
जमालिक

@jamylak सच है, लेकिन सभी वास्तविक विश्व स्थितियों या डेटा उस लचीलेपन की अनुमति नहीं देते हैं। उदाहरण के लिए, बहुत स्मृति के बिना सिस्टम पर एक-बंद विश्लेषण के माध्यम से "विरासत" भू-स्थानिक डेटा को पंप करना। फिर विचार करने के लिए प्रोग्रामिंग समय बनाम रनटाइम भी है। विकास के समय में बचत के कारण लोग अक्सर अजगर की ओर रुख करते हैं। इस उत्तर के साथ, मैं इस तथ्य की ओर ध्यान दिला रहा हूं कि स्मृति विचार करने लायक हो सकती है, लेकिन मैं अंत में बताता हूं कि यह नोटेशन में ज्यादातर व्यक्तिगत प्राथमिकता है। मैं यह भी बताता हूं कि डेटा जानना महत्वपूर्ण है। O(n^2)केवल तभी पूरी सूची है None
केविन

रुचि होगी यदि आपके पास एक व्यावहारिक उदाहरण है जहां यह उत्तर सबसे अच्छा समाधान है, तो मुझे लगता है कि सभी मामलों में बेहतर दृष्टिकोण होगा। उदाहरण के लिए numpyइस तरह के ऑपरेशन को अधिक अनुकूलित तरीके से संभालने में सक्षम होगा
जमैकाक

@jamylak निष्पक्ष होने के लिए, मैं numpyहाल के वर्षों में उपयोग कर रहा हूं , लेकिन यह एक अलग कौशल है। यदि पायथन के बजाय Lतत्काल किया जाता है , तो (stackoverflow.com/a/25255015/3003133) शायद या तो बेहतर है, लेकिन मुझे स्मृति के नीचे प्रसंस्करण के लिए कार्यान्वयन विवरण नहीं पता है। यह कम से कम मास्क के लिए बूलियन की एक डुप्लिकेट लंबाई सरणी बनाता है। किसी एक्सेस (इंडेक्स) ऑपरेटर के अंदर तुलना का सिंटैक्स, इस तरह से, मेरे लिए नया है। इस चर्चा ने भी मेरा ध्यान खींचा है । numpy.arraylistL = L[L != numpy.array(None)]dtype=object
केविन

यह चर्चा बहुत सारगर्भित हो रही है, मुझे नहीं लगता कि आप मुझे अपने वर्षों के अनुभव में एक वास्तविक जीवन का उदाहरण देने में सक्षम होंगे जहां यह उत्तर डेटा के पुनर्गठन पर सही दृष्टिकोण है जैसा कि मैंने पहले उल्लेख किया है।
जामिलाक

2
from operator import is_not
from functools import partial   

filter_null = partial(filter, partial(is_not, None))

# A test case
L = [1, None, 2, None, 3]
L = list(filter_null(L))

6
कृपया, ओपी को कुछ जानकारी दें, न कि केवल एक कोड।
लॉरेंट लैपर्ट

1
मैंने किया। आपको क्या लगता है?
med_abidi

खैर, यह ओपी सवाल का जवाब नहीं देता है। इसके बजाय इस उत्तर पर विचार करें: stackoverflow.com/a/16096769/1513933
लॉरेंट लैपर्ट

हाँ आप सही है। फ़िल्टर आंशिक के साथ एक समस्या थी।
med_abidi

2

यदि यह सभी सूचियों की सूची है, तो आप @ रेमंड के उत्तर को संशोधित कर सकते हैं

L = [ [None], [123], [None], [151] ] no_none_val = list(filter(None.__ne__, [x[0] for x in L] ) ) हालांकि अजगर 2 के लिए

no_none_val = [x[0] for x in L if x[0] is not None] """ Both returns [123, 151]"""

<< list_indice [0] चर में सूची के लिए यदि चर कोई नहीं है >>


1

कहो सूची नीचे दी गई है

iterator = [None, 1, 2, 0, '', None, False, {}, (), []]

यह केवल उन्हीं वस्तुओं को लौटाएगा जिनकी bool(item) is True

print filter(lambda item: item, iterator)
# [1, 2]

इसके बराबर है

print [item for item in iterator if item]

किसी को भी फ़िल्टर करने के लिए:

print filter(lambda item: item is not None, iterator)
# [1, 2, 0, '', False, {}, (), []]

के बराबर:

print [item for item in iterator if item is not None]

उन सभी वस्तुओं को प्राप्त करने के लिए जो फाल्स का मूल्यांकन करती हैं

print filter(lambda item: not item, iterator)
# Will print [None, '', 0, None, False, {}, (), []]
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.