2011-01-15 11 views
6

मेरे पास करने के लिए शब्दकोश मैप करने के लिए की तरहएक लाइन अभिव्यक्ति एक और

d = {'user_id':1, 'user':'user1', 'group_id':3, 'group_name':'ordinary users'} 

और "मानचित्रण" शब्दकोश की तरह शब्दकोश:

m = {'user_id':'uid', 'group_id':'gid', 'group_name':'group'} 

सभी मैं "की जगह" करने के लिए कुंजी के साथ पहले शब्दकोश में कुंजी चाहते हैं दूसरे से (उदाहरण के लिए 'uid', आदि के साथ 'user_id' को प्रतिस्थापित करें) मुझे पता है कि कुंजी अपरिवर्तनीय हैं और मुझे पता है कि इसे 'if/else' कथन के साथ कैसे किया जाए।

लेकिन शायद एक पंक्ति अभिव्यक्ति में ऐसा करने का कोई तरीका है?

+0

पायथन का कौन सा संस्करण? – orlp

+0

यूआईडी दूसरे में मूल्य है, कुंजी नहीं। आप क्या आउटपुट देखना चाहते हैं? –

उत्तर

15

ज़रूर:

d = dict((m.get(k, k), v) for (k, v) in d.items()) 
+2

यह डी के – mouad

+0

में डी (ए, वी) के लिए '(के, वी) में (के, वी) के लिए '(के, v) होना चाहिए। (और फिर से तय किया गया; 'आइटम' को विधि के रूप में बुलाया जाना चाहिए।) –

+1

पायथन 2.x के लिए, 'd.items()' के बजाय 'd.iteritems()' का उपयोग करना अधिक उचित होगा (लेकिन यह वास्तव में वास्तव में बड़े शब्दकोशों के लिए महत्वपूर्ण है)। Idiomatic v3 संस्करण जोड़ने के लिए –

5

3.x में:

d = {m.get(key, key):value for key, value in d.items()} 

यह एक नया शब्दकोश जो d से हर मान और नई कुंजी को मैप किया बनाकर काम करता है। कुंजी इस तरह से पुनर्प्राप्त की जाती है: m[key] if m in key else key, लेकिन फिर डिफ़ॉल्ट .get फ़ंक्शन के साथ (यदि कुंजी मौजूद नहीं है तो डिफ़ॉल्ट मानों का समर्थन करता है)।

+0

+1। –

0

आप इसे एक पंक्ति में क्यों करना चाहते हैं?

>>> d = dict((m.get(k, k), v) for (k, v) in d.items()) 
{'gid': 3, 'group': 'ordinary users', 'uid': 1, 'user': 'user1'} 

लेकिन यह कैसे काम करता है:

result = {} 
for k, v in d.iteritems(): 
    result[m.get(k, k)] = v 
+2

क्योंकि सूची/dict/कोई समझ बहुत पाइथोनस्क और तेज तेज है? – orlp

+0

"पायथनिक", लेकिन हाँ, बहुत कुछ है। –

13

के @karlknechtel से उत्कृष्ट कोड ले और देखें कि यह क्या करता है?

एक शब्दकोश बनाने के लिए, आप dict() फ़ंक्शन का उपयोग कर सकते हैं। यह tuples की एक सूची की उम्मीद है। 3.x और> 2.7 में, आप शब्दकोश समझ का भी उपयोग कर सकते हैं (@nightcracker द्वारा उत्तर देखें)।

चलो नियम के तर्क को विच्छेदन करते हैं। सबसे पहले, हमें एम में सभी वस्तुओं की एक सूची की आवश्यकता है। प्रत्येक आइटम प्रारूप (कुंजी, मूल्य) में एक tuple है।

>>> d.items() 
[('group_id', 3), ('user_id', 1), ('user', 'user1'), ('group_name', 'ordinary users')] 

एक महत्वपूर्ण मूल्य k देखते हुए, हम m[k] करके m से सही कुंजी मान मिल सकता है।

>>> k = 'user_id' 
>>> m[k] 
'uid' 

दुर्भाग्य से, नहीं d में सभी चाबियाँ भी m में मौजूद हैं।

>>> k = 'user' 
>>> m[k] 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
KeyError: 'user' 

कि हल करने के लिए, आप d.get(x, y), जो d[x] लौटाता है यदि कुंजी x मौजूद है, या डिफ़ॉल्ट मान y उपयोग कर सकते हैं, तो ऐसा नहीं है। अब, अगर dm में मौजूद नहीं है, तो हम इसे केवल रखते हैं, इसलिए डिफ़ॉल्ट k है।

>>> m.get(k, k). 
'user' 

अब हम dict() को आपूर्ति करने के लिए टुपल्स की एक सूची बनाने के लिए तैयार हैं। एक पंक्ति में एक सूची बनाने के लिए, हम list comprehension का उपयोग कर सकते हैं।

वर्गों की एक सूची का निर्माण करने के लिए, आप इस बारे में होगा:

>>> [x**2 for x in range(5)] 
[0, 1, 4, 9, 16] 

हमारे मामले में, यह इस तरह दिखता है:

>>> [(m.get(k, k), v) for (k, v) in d.items()] 
[('gid', 3), ('uid', 1), ('user', 'user1'), ('group', 'ordinary users')] 

एक कौर है कि, चलो फिर से उस पर नजर डालते हैं।

मुझे एक सूची [...], tuples के होते हैं जो दें:

[(.., ..) ...] 

मैं d में हर आइटम x के लिए एक टपल हैं:

[(.., ..) for x in d.items()] 

हम जानते हैं कि हर आइटम दो के साथ एक टपल है घटक, इसलिए हम इसे दो चर k और v तक विस्तारित कर सकते हैं।

[(.., ..) for (k, v) in d.items()] 

हर टपल पहले घटक, या कश्मीर अगर कश्मीर मीटर में मौजूद नहीं है, और घ से मूल्य के रूप में मीटर से सही कुंजी होना चाहिए।

[(m.get(k, k), v) for (k, v) in d.items()] 

हम इसे dict() पर तर्क के रूप में पास कर सकते हैं।

>>> dict([(m.get(k, k), v) for (k, v) in d.items()]) 
{'gid': 3, 'group': 'ordinary users', 'uid': 1, 'user': 'user1'} 

अच्छा लगता है! लेकिन प्रतीक्षा करें, आप कह सकते हैं, @karlknechtel स्क्वायर ब्रैकेट का उपयोग नहीं किया था।

दाएं, उन्होंने एक सूची समझ का उपयोग नहीं किया, लेकिन generator expression। बस बोलते हुए, अंतर यह है कि एक सूची समझ स्मृति में पूरी सूची बनाता है, जबकि जनरेटर अभिव्यक्ति एक समय में आइटम पर गणना करती है। यदि एक मध्यवर्ती परिणाम के रूप में कार्य करता है, तो आमतौर पर जनरेटर अभिव्यक्ति का उपयोग करना एक अच्छा विचार है। इस उदाहरण में, यह वास्तव में कोई फर्क नहीं पड़ता है, लेकिन यह उपयोग करने के लिए एक अच्छी आदत है।

बराबर जनरेटर भाव इस तरह दिखता है:

>>> ((m.get(k, k), v) for (k, v) in d.items()) 
<generator object <genexpr> at 0x1004b61e0> 

आप एक समारोह के लिए तर्क के रूप में एक जनरेटर अभिव्यक्ति पार कर लेते हैं, तो आप आमतौर पर बाहरी कोष्ठकों को छोड़ कर सकते हैं। अंत में, हम पाते हैं:

>>> dict((m.get(k, k), v) for (k, v) in d.items()) 
{'gid': 3, 'group': 'ordinary users', 'uid': 1, 'user': 'user1'} 

कोड की एक पंक्ति में बहुत कुछ होता है। कुछ कहते हैं कि यह अपठनीय है, लेकिन एक बार जब आप इसका इस्तेमाल कर लेंगे, तो इस कोड को कई लाइनों पर खींचना अपठनीय लगता है। बस इसे अधिक मत करो। सूची समझ और जनरेटर अभिव्यक्ति बहुत शक्तिशाली हैं, लेकिन महान शक्ति के साथ बड़ी ज़िम्मेदारी आती है। एक अच्छे सवाल के लिए +1!

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