2008-10-28 22 views
6

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

keys = ['name', 'age'] 
values = ['Monty', 42, 'Matt', 28, 'Frank', 33] 

वहाँ एक सीधा या कम से कम एक सरल शब्दकोशों की निम्न सूची का निर्माण करने के तरीका है?

[ 
    {'name': 'Monty', 'age': 42}, 
    {'name': 'Matt', 'age': 28}, 
    {'name': 'Frank', 'age': 33} 
] 

उत्तर

13

यहाँ जिप रास्ता

def mapper(keys, values): 
    n = len(keys) 
    return [dict(zip(keys, values[i:i + n])) 
      for i in range(0, len(values), n)] 
+0

एक चर नाम के रूप में एल (लोअरकेस ell) का उपयोग करना प्राणघातक पेप 8 उल्लंघन है। आपका पाइथनिंग लाइसेंस इस प्रकार निरस्त कर दिया गया है! ;) – ddaa

+0

धन्यवाद टोनी! मुझसे शादी करोगी !? मैं आपके उत्तर को स्वीकार करने के रूप में चिह्नित करता हूं, क्योंकि यह (अभी) सरल और आसान IMHO पढ़ने में आसान है। –

+0

ज़िप में सभी को एक सूची समझने के लिए ज़िप और स्लाइस ऑपरेटर के चरण भाग का उपयोग करें: [ज़िप (ज़िप [कुंजी, ए)) में ज़िप के लिए (मान [:: 2], मान [1 :: 2])] – jblocksom

2

बेवकूफ तरीका है, लेकिन एक है कि मेरे मन को तुरंत आता है:

def fields_from_list(keys, values): 
    iterator = iter(values) 
    while True: 
     yield dict((key, iterator.next()) for key in keys) 

list(fields_from_list(keys, values)) # to produce a list. 
+0

यह वास्तव में सूची नहीं बनाता है बल्कि तत्वों को उत्पन्न करता है। –

+0

ठीक है, इसे थोड़ा सा संशोधित करने दें। – Cheery

+0

बस 'सूची (फ़ील्ड_from_list (कुंजी, मान)) ' –

2

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

$ python 
>>> keys = ['name', 'age'] 
>>> values = ['Monty', 42, 'Matt', 28, 'Frank', 33] 
>>> dict(zip(keys, values)) 
{'age': 42, 'name': 'Monty'} 

/संपादित करें: ओह, आप एक सूची की dict चाहते हैं। निम्नलिखित कार्य (पीटर के लिए भी धन्यवाद):

from itertoos import cycle 

keys = ['name', 'age'] 
values = ['Monty', 42, 'Matt', 28, 'Frank', 33] 

x = zip(cycle(keys), values) 
map(lambda a: dict(a), zip(x[::2], x[1::2])) 
+0

का उपयोग करें आप सही हैं, एक ज़िप-जैसे फ़ंक्शन जो चक्र चाल करेगा। –

+0

'itertools.cycle' एक अनुक्रम दोहराएगा। तो 'dict (ज़िप (itertools.cycle (कुंजी), मूल्य)) 'इसे करना चाहिए। –

+0

पीटर, धन्यवाद, लेकिन मैंने अभी तक कोई सफलता नहीं की है। यह {'आयु': 33, 'नाम': 'फ्रैंक'} –

1

मेरा सरल दृष्टिकोण यहां है। ऐसा लगता है कि @ चेरी को छोड़कर मैंने इनपुट सूची को नष्ट कर दिया था।

def pack(keys, values): 
    """This function destructively creates a list of dictionaries from the input lists.""" 
    retval = [] 
    while values: 
    d = {} 
    for x in keys: 
     d[x] = values.pop(0) 
    retval.append(d) 
    return retval 
1

फिर भी एक और कोशिश है, शायद पहले एक से बेवकूफी:

def split_seq(seq, count): 
    i = iter(seq) 
    while True: 
     yield [i.next() for _ in xrange(count)] 

>>> [dict(zip(keys, rec)) for rec in split_seq(values, len(keys))] 
[{'age': 42, 'name': 'Monty'}, 
{'age': 28, 'name': 'Matt'}, 
{'age': 33, 'name': 'Frank'}] 

लेकिन यह है कि क्या यह बेवकूफी है तय करने के लिए आप पर निर्भर है।

2

जवाब में से Konrad Rudolph

ज़िप लगभग आप क्या चाहते हैं करता है; दुर्भाग्यवश, छोटी सूची में साइकिल चलाने की बजाए, यह टूट जाता है। शायद चक्र से संबंधित एक कार्य है?

यहाँ एक तरीका है:

keys = ['name', 'age'] 
values = ['Monty', 42, 'Matt', 28, 'Frank', 33] 
iter_values = iter(values) 
[dict(zip(keys, iter_values)) for _ in range(len(values) // len(keys))] 

मैं इसे नहीं देगा pythonic (मुझे लगता है कि यह बहुत चालाक है), लेकिन यह हो सकता है क्या के लिए देख रहे हैं।

वहाँ keys सूची itertools.cycle() का उपयोग कर साइकिल में कोई लाभ नहीं है, क्योंकि keys से प्रत्येक ट्रेवर्सल एक dictionnary के निर्माण से मेल खाती है है।

संपादित करें:

def iter_cut(seq, size): 
    for i in range(len(seq)/size): 
     yield seq[i*size:(i+1)*size] 

keys = ['name', 'age'] 
values = ['Monty', 42, 'Matt', 28, 'Frank', 33] 
[dict(zip(keys, some_values)) for some_values in iter_cut(values, len(keys))] 

यह बहुत अधिक pythonic है: एक स्पष्ट उद्देश्य के साथ एक पठनीय उपयोगिता समारोह है, और कोड के बाकी इसे से स्वाभाविक रूप से बहती है यहाँ एक और तरीका है।

+0

मैंने बदल दिया है '/' -> '//'। इस प्रकार कोड पायथन 3.0 और '__future__ आयात प्रभाग' से संगत हो गया। – jfs

3

यह बहुत नहीं है लेकिन यहाँ एक एक लाइनर एक सूची समझ, ज़िप और स्टेपिंग का उपयोग कर रहा है:

[dict(zip(keys, a)) for a in zip(values[::2], values[1::2])] 
+0

यह केवल 'लेन (कुंजी) == 2' के लिए काम करता है। – jfs

0
[dict(zip(keys,values[n:n+len(keys)])) for n in xrange(0,len(values),len(keys)) ] 

स्नातकीय-LEEE। मुझे ऐसा लगता है कि कोड देखने से नफरत है। लेकिन यह सही दिखता है।

def dictizer(keys, values): 
    steps = xrange(0,len(values),len(keys)) 
    bites = (values[n:n+len(keys)] for n in steps) 
    return (dict(zip(keys,bite)) for bite in bites) 

फिर भी एक छोटे से बदसूरत, लेकिन नाम इसके बारे में समझ बनाने में मदद।

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