9

I have:

list_nums = [1,18]
list_chars = ['a','d']

I want:

list_num_chars = [{'num':1, 'char':'a'},
                  {'num':18, 'char':'d'}]

Is there a more elegant solution than:

list_num_chars = [{'num':a, 'char':b} for a,b in zip(list_nums, list_chars)]
atp
  • 30,132
  • 47
  • 125
  • 187
  • 4
    Your solution is already elegant in that it is Pythonic, easy to read, and resembles the output. I'm not sure what else you could ask for :p – Kai Mar 06 '11 at 01:23
  • Do you mean that you want to have a sort of "macro" that will work on any such lists without having to change the names; e.g., if you pass it "list_foo", it will use the key "foo"? – Vamana Mar 06 '11 at 01:34
  • @Vamana: nope, nothing like that. – atp Mar 06 '11 at 01:46
  • Hey mods, *it's not duplicate*. Read the question carefully and look at the answers, if you know Python at all... – Adam May 19 '14 at 11:41

3 Answers3

4
map(dict, map(lambda t:zip(('num','char'),t), zip(list_nums,list_chars)))

gives:

[{'char': 'a', 'num': 1}, {'char': 'd', 'num': 18}]
PaulMcG
  • 62,419
  • 16
  • 94
  • 130
3

If the initial lists are very long, you might want to use itertools.izip() instead of zip() for slightly improved performance and less memory usage, but apart from this I can't think of a significantly "better" way to do it.

Sven Marnach
  • 574,206
  • 118
  • 941
  • 841
1

Declare a new variable which are the keys to your dict

from itertools import izip
nums  = [1,18]
chars = ['a','d']
keys  = ["num", "char"]      # include list of keys as an input

which gives a slightly more elegant solution, I think.

[dict(zip(keys,row)) for row in izip(nums,chars)]

It's definitely more elegant when there are more keys (which is why I started hunting for this solution in the first place :)

If you want, this tweak gives the same as a generator:

(dict(zip(keys,row)) for row in izip(nums,chars))
gabe
  • 2,521
  • 2
  • 25
  • 37