在列表中追加和添加包含字典作为元素的元素

时间:2018-06-12 20:00:37

标签: python list dictionary

有一个列表,其中包含字典作为其元素。每个字典作为多个键。我需要在给定键值的基础上添加其他键的值。 例如,有一个列表A:

A =
[{'count': 100, 'price': [100, 200, 300], 'quality': 'good', 'key': 'veg'}, {'count': 150, 'price': [10, 20, 30], 'quality': 'good', 'key': 'non-veg'}, {'count': 200, 'price': [1, 2, 3], 'quality': 'good', 'key': 'veg'}, {'count': 100, 'price': [110, 220, 330], 'quality': 'good', 'key': 'non-veg'}]

我正在尝试在' key'的基础上添加这些元素的值。值。我需要输出如:

[{'count': 300, 'price': [100, 200, 300, 1, 2, 3], 'quality': 'good', 'key': 'veg'}, {'count': 250, 'price': [10, 20, 30, 110, 220, 330], 'quality': 'good', 'key': 'non-veg'}]

我尝试使用itertools函数groupby和map。但 NOT 能够完全按预期获得结果。这有什么简单的方法吗?

2 个答案:

答案 0 :(得分:2)

尽管我喜欢groupby,但我认为这不是一个好主意。您的元素会替换vegnon-veg,但groupby期望这些群组是连续的,这意味着只有在您第一次呼叫sorted时,它才能正常工作这意味着你要反复抛弃做事的所有简单性和性能优势。

与此同时,如果不进行排序,建立一个关键字值的键盘要比键盘值更容易,而不是必须继续搜索每个键的列表。例如:

d = collections.defaultdict(lambda: dict(count=0, price=[], quality=''))
for entry in A:
    key = entry['key']
    target = d[key]
    target['count'] += entry['count']
    target['price'].extend(entry['price'])
    target['quality'] = 'something' # I don't know what your aggregation rule is

现在,d看起来像这样:

defaultdict(<function __main__.<lambda>>,
            {'non-veg': {'count': 250,
              'price': [10, 20, 30, 110, 220, 330]],
              'quality': 'something'},
             'veg': {'count': 300,
              'price': [100, 200, 300, 1, 2, 3]],
              'quality': 'something'}})

如果你真的需要最后的清单,那很简单:

[dict(key=key, **value) for key, value in d.items()]

或者,如果dict结构比列表更有用,那就使用它。 (如果您不希望dict.setdefault在以后的查找中变为默认值,请使用defaultdict代替d = dict(d),或最后执行KeyError,当然。)

答案 1 :(得分:0)

对于纯Python解决方案,collections.defaultdict可能是最佳选择。

如果您愿意使用第三方库,可以通过Pandas实现:

import pandas as pd
import numpy as np

# create dataframe from list of dictionaries
df = pd.DataFrame(A)

print(df)

   count      key            price quality
0    100      veg  [100, 200, 300]    good
1    150  non-veg     [10, 20, 30]    good
2    200      veg        [1, 2, 3]    good
3    100  non-veg  [110, 220, 330]    good

# define aggregation rules
agg_dict = {'price': lambda x: np.array(x.values.tolist()).sum(axis=0).tolist(),
            'count': np.sum,
            'quality': 'first'}

# apply aggregation rules
res = df.groupby('key').agg(agg_dict).reset_index()

print(res)

       key            price  count quality
0  non-veg  [120, 240, 360]    250    good
1      veg  [101, 202, 303]    300    good

然后产生你的字典结果:

d = res.to_dict(orient='records')

print(d)

[{'key': 'non-veg', 'price': [120, 240, 360], 'count': 250, 'quality': 'good'},
 {'key': 'veg', 'price': [101, 202, 303], 'count': 300, 'quality': 'good'}]