2012-09-11 9 views
20

कई बार मैंने सोचा है कि जनरेटर शैली और अधिक प्रत्यक्ष हो सकता है कि एक सूची लौट रहा, उदाहरण के लिए,क्या पाइथन में कोई लाइब्रेरी फ़ंक्शन है जो जनरेटर-फ़ंक्शन को किसी फ़ंक्शन को वापस करने के लिए चालू करता है?

def foo(input_array): 
    for x in input_array: 
     yield processed(x) 

बनाम

def bar(input_array): 
    accumulator = [] 
    for x in input_array: 
     accumulator.append(processed(x)) 
    return accumulator 

(ठीक है, अगर सचमुच यह इतना आसान थे , मैं map लिखूंगा, लेकिन आपको बिंदु मिल जाएगा: जेनरेटर संस्करण क्लीनर है)। हालांकि, जनरेटर का रिटर्न प्रकार हमेशा वांछित नहीं होता है। क्या कोई अंतर्निर्मित सजावट है जिसे मैं foo को किसी सूची या टुपल को वापस करने वाले फ़ंक्शन में बदलने के लिए उपयोग कर सकता हूं? जिस तरह से मैं लिखते हैं अपने आप को है,

import functools 

def transform_return_value(transformer): 
    def inner(f): 
     @functools.wraps(f) 
     def new_f(*argv, **kwargs): 
      return transformer(f(*argv, **kwargs)) 
     return new_f 
    return inner 

@transform_return_value(list) 
def foo(input_array): 
    for x in input_array: 
     yield processed(x) 
+8

रुको ... आप एक जनरेटर फ़ंक्शन लिखना चाहते हैं जो एक सूची देता है? मुझे यकीन नहीं है कि मैं इसे समझता हूं। क्यों न केवल 'सूची (जनरेटर_फंक्शन()) लिखें, या' list_function() 'लिखने के लिए क्यों लिखें? – mgilson

+0

एक और विकल्प सूची समझ का उपयोग करना है: '[input_array में x के लिए संसाधित (x)]'। दोनों से तर्कसंगत रूप से क्लीनर ... –

+1

@mgilson सही है: आमतौर पर जब आप किसी सूची की आवश्यकता होती है तो आप सूची में कनवर्ट करेंगे, जो हमेशा क्लाइंट कोड में है। मैं फ़ंक्शन को पुनरावर्तित करने के रूप में दस्तावेज़ों को दस्तावेज करता हूं और 'to_sequence (x)' फ़ंक्शन को प्रभावी रूप से करता हूं जो 'सूची (x) को प्रभावी रूप से करता है (x, अनुक्रम) अन्य x'। –

उत्तर

19
मेरी जानकारी के अनुसार करने के लिए

(और मैं, देखा है क्योंकि मैं वास्तव में एक ही बात सोच है), कोई: वहाँ करने का कोई सीधा रास्ता है यह मानक पुस्तकालय के साथ।

वहाँ unstdlib.py पुस्तकालय में एक अच्छी तरह से परीक्षण listify आवरण है, हालांकि यह है: https://github.com/shazow/unstdlib.py/blob/master/unstdlib/standard/list_.py#L149

def listify(fn=None, wrapper=list): 
    """ 
    A decorator which wraps a function's return value in ``list(...)``. 

    Useful when an algorithm can be expressed more cleanly as a generator but 
    the function should return an list. 

    Example:: 

     >>> @listify 
     ... def get_lengths(iterable): 
     ...  for i in iterable: 
     ...   yield len(i) 
     >>> get_lengths(["spam", "eggs"]) 
     [4, 4] 
     >>> 
     >>> @listify(wrapper=tuple) 
     ... def get_lengths_tuple(iterable): 
     ...  for i in iterable: 
     ...   yield len(i) 
     >>> get_lengths_tuple(["foo", "bar"]) 
     (3, 3) 
    """ 
    def listify_return(fn): 
     @wraps(fn) 
     def listify_helper(*args, **kw): 
      return wrapper(fn(*args, **kw)) 
     return listify_helper 
    if fn is None: 
     return listify_return 
    return listify_return(fn) 
+0

"मेरे द्वारा कॉपी की जाने वाली औजारों की मेरी लाइब्रेरी + परियोजनाओं के बीच चारों ओर पेस्ट करें" मुझे नहीं पता कि मुझे राहत मिली है या निराश है कि मैं अकेला नहीं हूं जो ऐसा करता है। मेरे पास पाइथन फ़ंक्शंस का एक मुट्ठी भर है जो इसे मेरी अधिकांश पायथन परियोजनाओं में शामिल करता है। प्रतिलिपि बनाना और पेस्ट करना सकल लगता है, लेकिन वे बहुत छोटे हैं (और एक दूसरे से असंबंधित) जो उन्हें पुस्तकालय में डालकर ओवरकिल की तरह लगते हैं। –

+0

आह हे! इस उत्तर को लिखने के बाद से मैंने बिल्कुल ऐसी लाइब्रेरी शुरू की है: https://github.com/shazow/unstdlib.py –

+0

मैं सजावटी को कुछ 'wrap_return'' कहूंगा, फिर 'listify = wrap_return (wrapper = list) '@listify (wrapper = काउंटर)' –

-2

कुशल और संक्षिप्त सूची परिभाषा देखने के लिए का उपयोग करने की सूची समझ:

def foo(input_array): 
    return [processed(x) for x in input_array] 

आप एक चाहते हैं एक सूची वापस करने के लिए समारोह, यह एक सूची वापस आ गया है। यह सजावटी का उपयोग करने से अधिक साफ, समझने, पढ़ने और डीबग करने में आसान है।

आप फ़ंक्शन को कॉल करने के बजाय, इनलाइन को लिखना पसंद कर सकते हैं।

+5

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

+0

@ डेविड और यह सूची समझ का उपयोग करने के लिए भी क्लीनर है! –

+3

हां, यह * विशिष्ट उदाहरण * एक सूची समझ के रूप में क्लीनर है। लेकिन सवाल यह नहीं है कि "मैं इस फ़ंक्शन के कार्यान्वयन को कैसे साफ कर सकता हूं?", सवाल यह है कि "क्या पाइथन में जनरेटर-फ़ंक्शन को एक सूची लौटने वाले फ़ंक्शन में बदलने के लिए लाइब्रेरी फ़ंक्शन है?" –

3

हालांकि @ दाऊद Wolever के जवाब suerly स्पष्ट तरीका है, एक बात मैं अक्सर अपने आप कर रही है (यह एक बाहरी डेकोरेटर को परिभाषित करने की आवश्यकता नहीं है के रूप में) इस तरह, एक स्थानीय समारोह के रूप में जनरेटर लिख रहा है लगता है:

def foo(input_array): 
    def gen(): 
     for x in input_array: 
      yield processed(x) 

    return list(gen()) 
संबंधित मुद्दे

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