2012-01-19 26 views
6

मेरे पास कुछ प्रकार का वर्बोज़ तर्क है कि मैं कुछ समझों के साथ संक्षिप्त करना चाहता हूं।संयुक्त सूची और dict समझ

अनिवार्य रूप से, मेरे पास एक निर्देश वस्तु है जिसे मैं पढ़ रहा हूं जिसमें से 16 मान हैं जिनसे मैं चिंतित हूं।

["I%d" % (i,) for i in range(16)] 

स्रोत शब्दकोश तरह का इस तरह दिखता है:: मैं कुंजी है कि मैं निम्नलिखित समझ के साथ चाहते हो रही है

{ "I0": [0,1,5,2], "I1": [1,3,5,2], "I2": [5,9,10,1], ... } 

मैं अनिवार्य रूप से इस शब्दकोश मैप करने के लिए की तरह कुछ होना चाहते हैं यह:

[ 
    { "I0": 0, "I1": 1, "I2": 5, ... } 
    { "I0": 1, "I1": 3, "I2": 9, ... } 
    ... 
] 

मैं अपने स्रोत dict को शब्दकोशों की अपनी गंतव्य सूची में बदलने के लिए सूची और शब्दकोश समझ के साथ चीजों को कैसे मैप कर सकता हूं?

उत्तर

7

यह एक पूर्ण कार्यात्मक समाधान है जिसे मनमाने ढंग से आकार पर लागू किया जा सकता है।

d = { "I0": [0,1,5,2], "I1": [1,3,5,2], "I2": [5,9,10,1]} 
map(dict, zip(*map(lambda (k, v): map(lambda vv: (k, vv), v), d.iteritems()))) 

विस्तृत करने के: (मैं ipython उपयोग कर रहा हूँ और अंडरस्कोर _ इसका मतलब पिछले उत्पादन)

In [1]: d = {'I0': [0, 1, 5, 2], 'I1': [1, 3, 5, 2], 'I2': [5, 9, 10, 1]} 

In [2]: map(lambda (k, v): map(lambda vv: (k, vv), v), _.iteritems()) 
Out[2]: 
[[('I1', 1), ('I1', 3), ('I1', 5), ('I1', 2)], 
[('I0', 0), ('I0', 1), ('I0', 5), ('I0', 2)], 
[('I2', 5), ('I2', 9), ('I2', 10), ('I2', 1)]] 

In [3]: zip(*_) 
Out[3]: 
[(('I1', 1), ('I0', 0), ('I2', 5)), 
(('I1', 3), ('I0', 1), ('I2', 9)), 
(('I1', 5), ('I0', 5), ('I2', 10)), 
(('I1', 2), ('I0', 2), ('I2', 1))] 

In [4]: map(dict, _) 
Out[4]: 
[{'I0': 0, 'I1': 1, 'I2': 5}, 
{'I0': 1, 'I1': 3, 'I2': 9}, 
{'I0': 5, 'I1': 5, 'I2': 10}, 
{'I0': 2, 'I1': 2, 'I2': 1}] 
6

मैं कैसे इसे हल होगा: सबसे पहले

, मैं प्रत्येक कुंजी के लिए मिलेगा एक सूची जिसमें टुपल्स होते हैं, जहां पहला आइटम कुंजी होगा और दूसरा एक सूची से मूल्यों में से एक होगा:

>>> [ [ (k, i) for i in l] for k, l in d.items() ] 
[[('I1', 1), ('I1', 3), ('I1', 5), ('I1', 2)], 
    [('I0', 0), ('I0', 1), ('I0', 5), ('I0', 2)], 
    [('I2', 5), ('I2', 9), ('I2', 10), ('I2', 1)]] 

तब मैं इस सूची अनुप्रस्थ हैं, प्रत्येक इसी कुंजी वाला tuples की एक सूची बनाने, ज़िप फ़ंक्शन का उपयोग:

>>> [dict(lp) for lp in zip(*[ [ (k, i) for i in l] for k, l in d.items() ])] 
[{'I0': 0, 'I1': 1, 'I2': 5}, 
{'I0': 1, 'I1': 3, 'I2': 9}, 
{'I0': 5, 'I1': 5, 'I2': 10}, 
{'I0': 2, 'I1': 2, 'I2': 1}] 

:

>>> list(zip(*[ [ (k, i) for i in l] for k, l in d.items() ])) 
[(('I1', 1), ('I0', 0), ('I2', 5)), 
(('I1', 3), ('I0', 1), ('I2', 9)), 
(('I1', 5), ('I0', 5), ('I2', 10)), 
    (('I1', 2), ('I0', 2), ('I2', 1))] 

इन उप-सूचियों dict निर्माता को पैरामीटर के रूप में पारित कर दिया जा सकता है प्रैक्टिस में, हालांकि, मैं कभी भी एक पंक्ति में ऐसी चीज करने की सलाह नहीं दूंगा:

>>> pairs = [ [ (k, i) for i in l] for k, l in d.items() ] 
>>> transversed = zip(*pairs) 
>>> ds = [dict(t) for t in transversed] 
>>> pprint(ds) 
[{'I0': 0, 'I1': 1, 'I2': 5}, 
{'I0': 1, 'I1': 3, 'I2': 9}, 
{'I0': 5, 'I1': 5, 'I2': 10}, 
{'I0': 2, 'I1': 2, 'I2': 1}] 

असल में, मैं wo उल ने कहा कि मैंने यह उत्तर अधिकतर पोस्ट करने के लिए आपको एक से अधिक पंक्ति में अपने समाधान को विभाजित करने का सुझाव दिया है।

+0

+1। हमारे दृष्टिकोण समान हैं, सिवाय इसके कि मैंने 'मानचित्र' का व्यापक उपयोग किया :) – qiao

+0

@qiao हां, हमने एक ही दृष्टिकोण को एक और अमूर्त तरीके से अपनाया। मुझे सूची समझ के लिए कुछ वरीयता है लेकिन आपका समाधान उत्कृष्ट है। – brandizzi

0

वहाँ छोटा और आसान समाधान है:

keys = data.keys() 
values = data.values() 
transformed = [dict(zip(keys, t)) for t in zip(*values)] 

कुंजी यहाँ मूल्यों मैट्रिक्स, जो zip(*values) साथ किया जाता है transposing है, तो हम सिर्फ dicts फिर से संगठित। चरण-दर-चरण विस्तार के लिए

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