2012-04-06 31 views
6

काल्पनिक समारोह repeatcall, कि नो-आर्ग प्रतिदेय func और उसे धन पूर्णांक n तर्कों के रूप लेता है, और रिटर्न जिसके सदस्य func()n बार क्रियान्वित करते हुए प्राप्त कर रहे हैं एक सूची पर विचार करें। ऐसा लगता है कि मूर्ख hijinks की एक अनंत धारा का समर्थन करता है:फ़ंक्शन को बार-बार कॉल करने के लिए फ़ंक्शन?

>>> repeatcall(lambda: id(dict()), 5) 
[45789920, 45788064, 45807216, 45634816, 45798640] 

>>> urandom = lambda: struct.unpack('Q', open('/dev/urandom').read(8))[0] 
>>> repeatcall(urandom, 3) 
[3199039843823449742, 14990726001693341311L, 11583468019313082272L] 

>>> class Counter(itertools.count): __call__ = itertools.count.next 
>>> repeatcall(Counter(100, -2), 4) 
[100, 98, 96, 94] 

मैं कसम खाता हूँ सकता है कि मैं repeatcall पायथन 2.x मानक पुस्तकालयों में कहीं की तरह एक समारोह देखा है, लेकिन मैं यह नहीं मिल सकता है। अगर मैंने यह सपना देखा नहीं है, तो मानक लाइब्रेरी में क्या मुझे यह मिल सकता है?

पीएस: मुझे पता है कि यह खुद को रोल करने के लिए छोटा है, लेकिन मुझे पहियों को फिर से शुरू करने से नफरत है, खासकर वे मानक पुस्तकालय में हैं। मैं हूं कि मैं खुद को कैसे रोल करना चाहता हूं।

संपादित करें: यह और भी अधिक स्पष्ट है कि मैं नहीं कह रहा हूँ कि कैसे repeatcall कोड करने के लिए बनाया है।

+1

क्या यह सिर्फ एक सीमा में मैपिंग नहीं है? – gbulmer

उत्तर

13

लिखा जा सकता है आप मानक पुस्तकालय डॉक्स में इस देखा है, मानक पुस्तकालय ही नहीं।

यह itertools recipes से repeatfunc है:

def repeatfunc(func, times=None, *args): 
    """Repeat calls to func with specified arguments. 

    Example: repeatfunc(random.random) 
    """ 
    if times is None: 
     return starmap(func, repeat(args)) 
    return starmap(func, repeat(args, times)) 

यह तर्क अनुमति देता है और चाहिए (सैद्धांतिक रूप से) एक सूची समझ तुलना में बेहतर प्रदर्शन क्योंकि func केवल एक बार देखा जाना चाहिए। repeatrange से भी तेज़ है जब आप वास्तव में काउंटर का उपयोग नहीं कर रहे हैं।

+1

तकनीकी रूप से आपका सटीक उत्तर नहीं है, जब तक आप यह नहीं कह रहे कि यह stdlib में मौजूद नहीं है। मुझे नहीं लगता कि 'itertools.starmap' का उपयोग करने वाला नुस्खा अपने आप को रोल करने से अलग है। हालांकि मुझे यह दिखाकर लगता है, आप इस बारे में एक दौर में हैं कि आपको अपना खुद का रोल करना है। – jdi

+1

@jdi हां, मैं रह रहा हूं यह मानक पुस्तकालय में मौजूद नहीं है। वह इसे देखकर याद करता है क्योंकि यह दस्तावेज़ों में है। यही उनके सवाल का जवाब है। – agf

+1

तब मुझे लगता है कि आपने जो लिखा है उसका 9 0% आवश्यक नहीं है यदि वह कोड के किसी भी कार्यान्वयन को देखने में रूचि नहीं रखता है। तो वास्तव में, वह 9 0% दूसरों की तरह ही है। – jdi

3

आप कुछ मतलब यह ?: तरह

>> from random import random 
>> print [random() for x in range(5)] 
[0.015015074309405185, 
0.7877023608913573, 
0.2940706206824023, 
0.7140457069245207, 
0.07868376815555878] 

काफी संक्षिप्त लगता नहीं है?

+2

"मुझे पता है कि खुद को रोल करने के लिए यह छोटा है, लेकिन मुझे पहियों को फिर से शुरू करने से नफरत है" - यह सवाल का जवाब नहीं देता है। – agf

2

आप apply में निर्मित समारोह इस उद्देश्य के

>>> def repeatcall(func,n): 
    [apply(func) for i in range(0,n)] 

>>> repeatcall(lambda: id(dict()), 5) 
[56422096, 56422240, 56447024, 56447168, 56447312] 

>>> import itertools 
>>> class Counter(itertools.count): __call__ = itertools.count.next 

>>> repeatcall(Counter(100, -2), 4) 
[100, 98, 96, 94] 
>>> 

नोट ** के लिए का उपयोग) (args, ** कीवर्ड *) का उपयोग कर सकते हैं मैनुअल से लागू (समारोह के बराबर है।

तो repeatcall के रूप में भी

>>> def repeatcall(func,n): 
    [func() for i in range(0,n)] 
+1

'लागू' को python2.3 के बाद से हटा दिया गया है। आप फ़ंक्शन को अपने * args और ** kwargs – jdi

+0

के साथ कॉल कर सकते हैं, फ़ंक्शन को सीधे कॉल किया जा सकता है, भले ही उसका नाम तर्क के रूप में पारित हो: def repeatcall (func, n): रेंज में [func() (0, एन)] –

+0

हां आवेदन यहां और हर जगह पूरी तरह से अनावश्यक है। –

3

ऐसा कोई कारण नहीं है कि यह अस्तित्व में नहीं है: एक ऐसे फ़ंक्शन को कोड करने का मूर्ख तरीका जो प्रत्येक आमंत्रण पर तर्क नहीं लेता है, और कुछ नया देता है उसे जनरेटर के रूप में कोड करना है।

फिर आप इसे जितनी बार चाहें उतनी बार कॉल करने के लिए एक सूची समझ या जनरेटर अभिव्यक्ति का उपयोग करेंगे: [next(gen) for i in xrange(5)]। अभी तक बेहतर, gen स्वयं जनरेटर अभिव्यक्ति का परिणाम हो सकता है जैसे (id(dict()) for i in (itertools.repeat(None)))

इस प्रकार, पायथन के लिए इसके लिए कोई लाइब्रेरी समर्थन नहीं है क्योंकि यह इसे वाक्य रचनात्मक रूप से समर्थन देता है।

+0

आप सही हैं, यह 'itertools' व्यंजनों में समाधान की तुलना में अधिक "पायथनिक" है। लेकिन, अन्य सभी की तरह, यह सवाल का जवाब नहीं है। वह पूछ रहा था कि उसने एक कार्यान्वयन देखा था, न कि इसे कैसे किया जाए। यह एक अच्छी टिप्पणी होगी। – agf

+1

@agf वास्तव में नहीं। इसके लिए लीस दो पैराग्राफ की आवश्यकता होती है, और यह समझाता है कि ओपी के लिए पूछे जाने वाले फॉर्म का कोई समाधान क्यों नहीं है। – Marcin

+0

उनका प्रश्न "मानक पुस्तकालय में नहीं है", यह है "मैंने इसे पहले देखा है; मुझे लगता है कि यह मानक पुस्तकालय में था लेकिन मुझे यह नहीं मिला। यह कहां है?" एक टिप्पणी 500 अक्षर फिट बैठता है; आपकी पोस्ट में अतिरिक्त जगह है, और कोई प्रारूपित ब्लॉक नहीं है जिसे आप टिप्पणी में प्रदर्शित नहीं कर सकते हैं। – agf

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