повторное объединение списка / словаря в python - PullRequest
1 голос
/ 03 ноября 2010

следующий за этот вопрос

у меня есть следующие списки в python, которые я хочу объединить в словарь / список:

из

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

до

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

Какой лучший способ сделать это , чтобы я мог иметь n свойств , перечисленных в fromfruits?

пожалуйста, помогите!:)

Ответы [ 6 ]

4 голосов
/ 03 ноября 2010

Поскольку запрос теперь должен быть более общим:

>>> 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'}]

, поскольку порядок keys и values одинаков (при условии отсутствия промежуточных модификаций словаря).

3 голосов
/ 03 ноября 2010

Было бы довольно сложно перейти от клавиш типа «имена» к «имени», обучая программу правильному использованию английского языка в единственном числе ... поэтому я переименовал ключи во входных данных:

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

Вы можете решить эту проблему снова с помощью zip:

# 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'}, ... ]
1 голос
/ 03 ноября 2010
[dict((x, fromfruits[x][n]) for x in fromfruits.keys())
  for n in range(len(next(fromfruits.itervalues())))]

Оптимизируйте по желанию.

0 голосов
/ 03 ноября 2010

Эта проблема несколько сложнее, чем усреднение списка, из-за вложенных словарей.

Однако , если вы можете создать правильную итерацию, тогда понимание списка - путь.

Попробуйте:

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

Здесь *Функция 1010 * используется для создания кортежей, которые соответствуют правильным name и color.Это хороший способ, потому что оба хранятся в основных списках в пределах fromfruits dict.

Эти кортежи (из zip) затем распаковываются в n и c, которыезатем используется как в типичном понимании списка.

0 голосов
/ 03 ноября 2010

не очень питон, но ...

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]
0 голосов
/ 03 ноября 2010
>>> 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'}]

А теперь более подробно (переформатировано для ясности):

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

Это «понимание списка» с двойным for, которое охватывает все комбинации имен ицвета.Вы можете добавить третий цикл, если хотите смешать другие атрибуты, такие как «форма» или что-то еще.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...