开发者

re-combining a list/dictionary in python

开发者 https://www.devze.com 2023-01-23 12:51 出处:网络
following o开发者_Go百科n from this question i have the following lists in python which i want to recombine into a dictionary/list:

following o开发者_Go百科n from this question

i have the following lists in python which i want to recombine into a dictionary/list:

from

fromfruits = { "names" : ['banana','grapefruit','apple'] , "colors" : ['yellow','pink','green'], ... }

to

tofruits = [
{'name':'banana','color':'yellow',...}, 
{'name':'grapefruit','color':'pink',...},
{'name':'apple','color':'green',...}
]

what's the best way to do it so that i can have n properties listed in fromfruits?

please help! :)


Since the request is now to be more general:

>>> from itertools import izip
>>> ff = {'colors': ['yellow', 'pink', 'green'], 'names': ['banana', 'grapefruit', 'apple'], 'blah': ['a','b','c']}

>>> [dict(izip(ff.iterkeys(), v)) for v in izip(*ff.itervalues())]
[{'blah': 'a', 'colors': 'yellow', 'names': 'banana'},
 {'blah': 'b', 'colors': 'pink', 'names': 'grapefruit'},
 {'blah': 'c', 'colors': 'green', 'names': 'apple'}]

since the order of keys and values are the same (assuming no intervening modifications to the dictionary).


It'd be pretty hard to go from keys like 'names' to 'name', teaching the program how to do proper english singlularization ... so i renamed the keys in the input:

ff = dict(name=['banana','grapefruit','apple'], color=['yellow','pink','green'], 
          yummy=[True,False,True])

You can solve this problem with zip again:

# make fruits [('yellow', True, 'banana'), ('pink', False, 'grapefruit'), ... ]
fruits = zip(*ff.itervalues())

# then add the names to each fruit
tofruits = [dict(zip(ff.iterkeys(),fruit)) for fruit in fruits]
# gives: [{'color': 'yellow', 'yummy': True, 'name': 'banana'}, ... ]


[dict((x, fromfruits[x][n]) for x in fromfruits.keys())
  for n in range(len(next(fromfruits.itervalues())))]

Optimize as desired.


>>> fromfruits
{'colors': ['yellow', 'pink', 'green'], 'names': ['banana', 'grapefruit', 'apple']}
>>> [{'name': name, 'color': color} for name in fromfruits['names'] for color in fromfruits['colors']]
[{'color': 'yellow', 'name': 'banana'}, {'color': 'pink', 'name': 'banana'}, {'color': 'green', 'name': 'banana'}, {'color': 'yellow', 'name': 'grapefruit'}, {'color': 'pink', 'name': 'grapefruit'}, {'color': 'green', 'name': 'grapefruit'}, {'color': 'yellow', 'name': 'apple'}, {'color': 'pink', 'name': 'apple'}, {'color': 'green', 'name': 'apple'}]

And now in some more detail (re-formatted for clarity):

>>>[{'name': name, 'color': color} 
        for name in fromfruits['names'] 
        for color in fromfruits['colors']]

This is a "list comprehension" with a double for which goes over all combinations of names and colors. You can add a third loop if you want to mix in other attributes, like "shape" or whatever.


not very pythonic, but ...

keys = fromfruits.keys()
nvals = len(fromfruits[keys[0]])
tofruits = [ ]
for i in range(nvals):
    tofruits.append ({ })
    for k in keys:
        tofruits[-1][k] = fromfruits[k][i]


This problem is a bit more convoluted than the average list comprehension because of the nested dictionaries.

However if you can create the right iterable then a list comprehension is the way to go.

Try:

tofruits = [ {'name':n, 'color':c} for n,c in zip(fromfruits['names'], 
                                              fromfruits['colors']) ]

Here the zip function is used to produce tuples which match the correct name and color. This is a good way to go here because both are stored in basic lists within the fromfruits dict.

These tuples (from zip) are then unpacked into n and c, which are then used as in a typical list comprehension.

0

精彩评论

暂无评论...
验证码 换一张
取 消