किसी समारोह में शब्दकोष को खोजशब्द मापदंडों के रूप में पास करना


346

मैं एक शब्दकोश का उपयोग करके अजगर में एक फ़ंक्शन को कॉल करना चाहता हूं।

यहाँ कुछ कोड है:

d = dict(param='test')

def f(param):
    print(param)

f(d)

यह प्रिंट करता है, {'param': 'test'}लेकिन मैं इसे सिर्फ प्रिंट करना चाहता हूं test

मैं इसे और अधिक मापदंडों के लिए इसी तरह काम करना चाहूंगा:

d = dict(p1=1, p2=2)
def f2(p1, p2):
    print(p1, p2)
f2(d)

क्या यह संभव है?

जवाबों:


528

अंत में खुद के लिए यह पता लगा। यह सरल है, मैं शब्दकोश को अनपैक करने के लिए बस ** ऑपरेटर को याद कर रहा था

तो मेरा उदाहरण बनता है:

d = dict(p1=1, p2=2)
def f2(p1,p2):
    print p1, p2
f2(**d)

57
यदि आप यह चाहते हैं कि आप दूसरों की मदद करें, तो आपको अपने प्रश्न को फिर से लिखना चाहिए: समस्या एक शब्दकोष नहीं थी, जो आप चाहते थे वह कीवर्ड मापदंडों में एक तानाशाही मोड़ रहा था
जेवियर

11
यह ध्यान देने योग्य है कि आप सूचियों को अनौपचारिक दलीलों में भी अनपैक कर सकते हैं: f2 (* [1,2])
मैथ्यू ट्रेवर

10
"डेरेफेरेंस": सामान्य शब्द, इस पायथन संदर्भ में, "अनपैक" है। :)
मिपाडी

2
यह बहुत अच्छा है, बस इसे एक वर्ग वस्तु के लिए विकल्पों में सीधे कमांड लाइन तर्क पार्स करने में आसान बनाने के लिए argparse / __ डिक्टी__ के साथ उपयोग किया।
होरस

1
ऐसा क्या कारण है कि हम किसी डिक्शनरी के तर्क के रूप में इसे डिक्शनरी में अनपैक करना चाहते हैं?
मोना जलाल

128
In[1]: def myfunc(a=1, b=2):
In[2]:    print(a, b)

In[3]: mydict = {'a': 100, 'b': 200}

In[4]: myfunc(**mydict)
100 200

कुछ अतिरिक्त विवरण जो जानना उपयोगी हो सकते हैं (यह पढ़ने के बाद मेरे पास जो सवाल थे और गए और परीक्षण किए गए):

  1. फ़ंक्शन में पैरामीटर हो सकते हैं जो नहीं हैं जो शब्दकोश में शामिल हैं
  2. आप एक पैरामीटर को ओवरराइड नहीं कर सकते जो पहले से ही डिक्शनरी में है
  3. डिक्शनरी में ऐसे पैरामीटर नहीं हो सकते जो फ़ंक्शन में नहीं हैं।

उदाहरण:

नंबर 1: फ़ंक्शन में ऐसे पैरामीटर हो सकते हैं जो शब्दकोश में शामिल नहीं हैं

In[5]: mydict = {'a': 100}
In[6]: myfunc(**mydict)
100 2

नंबर 2: आप एक पैरामीटर को ओवरराइड नहीं कर सकते जो पहले से ही डिक्शनरी में है

In[7]: mydict = {'a': 100, 'b': 200}
In[8]: myfunc(a=3, **mydict)

TypeError: myfunc() got multiple values for keyword argument 'a'

नंबर 3: शब्दकोश में ऐसे पैरामीटर नहीं हो सकते जो फ़ंक्शन में नहीं हैं।

In[9]:  mydict = {'a': 100, 'b': 200, 'c': 300}
In[10]: myfunc(**mydict)

TypeError: myfunc() got an unexpected keyword argument 'c'

जैसा कि टिप्पणियों में अनुरोध किया गया है, नंबर 3 का समाधान फ़ंक्शन में उपलब्ध कीवर्ड तर्कों के आधार पर शब्दकोश को फ़िल्टर करना है:

In[11]: import inspect
In[12]: mydict = {'a': 100, 'b': 200, 'c': 300}
In[13]: filtered_mydict = {k: v for k, v in mydict.items() if k in [p.name for p in inspect.signature(myfunc).parameters.values()]}
In[14]: myfunc(**filtered_mydict)
100 200

एक अन्य विकल्प अपने कार्य में अतिरिक्त kwargs को स्वीकार करना (और अनदेखा करना) है:

In[15]: def myfunc2(a=None, **kwargs):
In[16]:    print(a)

In[17]: mydict = {'a': 100, 'b': 200, 'c': 300}

In[18]: myfunc2(**mydict)
100

इससे आगे नोटिस करें कि आप स्थितिगत तर्कों और सूचियों या tuples का प्रभावी रूप से उसी तरह उपयोग कर सकते हैं जैसे कि kwargs, यहाँ एक और अधिक उन्नत उदाहरण स्थितीय और कीवर्ड args को शामिल किया गया है:

In[19]: def myfunc3(a, *posargs, b=2, **kwargs):
In[20]:    print(a, b)
In[21]:    print(posargs)
In[22]:    print(kwargs)

In[23]: mylist = [10, 20, 30]
In[24]: mydict = {'b': 200, 'c': 300}

In[25]: myfunc3(*mylist, **mydict)
10 200
(20, 30)
{'c': 300}

4
प्रिंट.फॉर्म के साथ अनपैकिंग का उपयोग करना विशेष रूप से उपयोगी है। जैसे:'hello {greeting} {name}'.format( **{'name': 'Andrew', 'greeting': 'Mr'})
मार्तार्क

पुराना सवाल है लेकिन फिर भी बहुत प्रासंगिक है। विस्तृत प्रतिक्रिया के लिए धन्यवाद। क्या आप केस 3 के आसपास काम करने का कोई तरीका जानते हैं? मतलब pythonically फंक्शन के आइटम्स को फंक्शन पैरामीटर्स में मैप करते हैं, जब डिक्शनरी में डिमांड के मुकाबले ज्यादा आइटम होते हैं?
स्पेंसर

2
@spencer जवाब में एक समाधान जोड़ा गया है।
डेविड पार्क

33

अजगर में, इसे "अनपैकिंग" कहा जाता है, और आप ट्यूटोरियल में इसके बारे में थोड़ा जान सकते हैं । इसका दस्तावेज़ीकरण बेकार है, मैं सहमत हूँ, विशेष रूप से क्योंकि यह कैसे fantasically उपयोगी है।


20
लिंक के प्रासंगिक सामग्री को अपने उत्तर में कॉपी करना बेहतर है, बजाय लिंक पर निर्भर रहने के समय के अंत तक जीवित रहने के लिए।
रिचर्ड

3
@ रीचर्ड वेब के बारे में एक गहरी दार्शनिक राय है, जिसके साथ मैं अधिक दिल से असहमत नहीं हो सकता! काश, मुझे अपने अद्भुत साक्ष्य को साझा करने के लिए यहाँ इस जगह की कमी महसूस होती ...
llimllib

@llimllib, मुझे डॉ। विल्स से पूछना होगा!
रिचर्ड

6

यहाँ फिर जाओ - बस किसी भी अन्य चलने योग्य काम करता है:

d = {'param' : 'test'}

def f(dictionary):
    for key in dictionary:
        print key

f(d)

ऐसा लगता है कि लोग इसे नकार रहे हैं क्योंकि इसने मूल प्रश्न का उत्तर दिया था, न कि पुनर्विकसित प्रश्न का। मेरा सुझाव है कि अभी इस पोस्ट को हटा दें।
डॉटनचेन

@dotancohen नहीं यह कभी सही नहीं था, यह कोड के दूसरे ब्लॉक को विफल करता है जो हमेशा सवाल के साथ था। इसे बहुत शाब्दिक रूप से लिया, प्रिंट एक उदाहरण था।
डेव हिलियर

हालांकि यह सवाल का जवाब देता है, यह सिर्फ शब्दकोश अनपैकिंग के माध्यम से नहीं करता है। पोस्ट किए गए प्रश्न के आधार पर उनका दृष्टिकोण पूरी तरह से मान्य है।
नैटचैट
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.