2012-01-24 13 views
18

मैं itertools मॉड्यूल से अधिक परिचित होने की कोशिश कर रहा हूं और ifilter नामक एक फ़ंक्शन मिला है।itertools.ifilter बनाम। फ़िल्टर बनाम सूची समझ

जो मैं समझता हूं उससे, यह दिए गए फ़ंक्शन के आधार पर फ़िल्टर और पुन: प्रयोज्य होता है और एक पुनरावर्तक के तत्वों को एक पुनरावर्तक देता है जिस पर फ़ंक्शन True पर मूल्यांकन करता है।

प्रश्न 1: क्या मेरी समझ इस प्रकार सही है?

प्रश्न 2: तथ्य यह है कि यह रिटर्न और इटेटरेटर, अंतर्निहित filter फ़ंक्शन से अलग कैसे है?

प्रश्न 3 कौन सा तेज़ है?

जो मैं कह सकता हूं, वह नहीं है। क्या मैं कुछ भूल रहा हूँ? (मैं निम्नलिखित परीक्षण भाग गया)

>>> itertools.ifilter(lambda x: x%2, range(5)) 
<itertools.ifilter object at 0x7fb1a101b210> 
>>> for i in itertools.ifilter(lambda x: x%2, range(5)): print i 
... 
1 
3 
>>> filter(lambda x: x%2, range(5)) 
[1, 3] 
>>> function = lambda x: x%2 
>>> [item for item in range(5) if function(item)] 
[1,3] 
+0

आप क्या उत्पादन अपेक्षा की थी? 'रेंज (5)' आपको '0,1,2,3,4]' देगी। – istruble

+1

ध्यान दें कि फ़िल्टर के अधिकांश उपयोग जेनरेटर/सूची अभिव्यक्ति पर एक गार्ड द्वारा प्रतिस्थापित किया जा सकता है: 'सूची (x में x के लिए x (x) x x 2) ' –

उत्तर

10

नीचे दिए गए उदाहरण में एक संख्या जनरेटर शामिल है जो संख्या उत्पन्न करने से पहले तुरंत एक संदेश प्रिंट करता है, यह दिखाता है कि filter() पहले सूची बनाता है, फिर उसके माध्यम से चलता है और इसे फ़िल्टर करता है। जबकि itertools.ifilter फिल्टर के रूप में यह जाता है, कभी भी एक सूची नहीं बनाते हैं।यदि आप 500,000 महत्वपूर्ण चीजें फ़िल्टर कर रहे हैं, तो आप ifilter चाहते हैं, इसलिए आप एक सूची नहीं बना रहे हैं।

import itertools 

def number_generator(): 
    for i in range(0, 3): 
     print "yield", i 
     yield i 
    print "stopping" 

function = lambda x: x > 0 

numbers = number_generator() 
print "itertools.ifilter:" 
for n in itertools.ifilter(function, numbers): 
    print n 

print "\nfilter:" 
numbers = number_generator() 
for n in filter(function, numbers): 
    print n 

आउटपुट:

 
itertools.ifilter: 
yield 0 
yield 1 
1 
yield 2 
2 
stopping 

filter: 
yield 0 
yield 1 
yield 2 
stopping 
1 
2 
3

ifilter एक जनरेटर, नहीं एक सूची देता है।

जेनरेटर पूरी सूची को पहले आवंटित करने के बजाय, आवश्यकतानुसार अपनी वस्तुओं को उड़ाने पर बनाते हैं। यही कारण है कि यही एक अंतर है ifilter और filter

+1

एक जनरेटर एक पुनरावर्तक है, और सख्त होने के लिए एक itertools.ifilter वस्तु। –

2

यहाँ के बीच, आप diference देख सकते हैं:

filter(function, iterable): iterable की उन तत्वों जिसके लिए समारोह सच रिटर्न से एक सूची का निर्माण।

itertools.ifilter(predicate, iterable): एक iterator कि लौटने के लिए केवल उन जिसके लिए विधेय यह सच है iterable से तत्वों फिल्टर करें।

इसका मतलब है कि 'ifiltered' आइटम प्राप्त करने के लिए आपको लौटाए गए पुनरावर्तक के साथ पुनरावृत्ति करना चाहिए, लेकिन 'फिल्टर' सभी तत्वों को एक पुनरावृत्ति के साथ सूची में वापस लाता है।

17

आपकी समझ corret है: फर्क सिर्फ इतना है कि ifilter पुनरावर्तक देता है, जबकि filter का उपयोग कर बुला की तरह है:

:

list(ifilter(...)) 

तुम भी में क्या PEP 289 फिल्टर और IFilter के बारे में कहते हैं दिलचस्पी हो सकती है

सूची की समझ ने filter() और map() की आवश्यकता को बहुत कम कर दिया। इसी तरह, जेनरेटर एक्सप्रेशन से itertools.ifilter() और itertools.imap() की आवश्यकता को कम करने की अपेक्षा की जाती है। [...]

भी ध्यान रखें कि ifilter बन गया अजगर -3 में filter (इसलिए itertools से हटा दिया)।

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