根据匹配值合并字典列表

时间:2018-06-13 13:57:30

标签: python list dictionary

我有一组类似的数据:

                this._htmlClient.get('../../assets/images/chart1.svg').subscribe(data => {
                    console.log('svg-file: ', data);
                });

我正在寻找一种有效的方法来为字典列表中的每个匹配trades = [{'ORDERID': 123, 'LEAVESQTY': 2200}, {'ORDERID': 123, 'LEAVESQTY': 500}, {'ORDERID': 456, 'LEAVESQTY': 100}, {'ORDERID': 789, 'LEAVESQTY': 300}] 找到LEAVESQTY的最低值。

例如,我对此示例的期望结果是:

ORDERID

我尝试应用与基于匹配键值合并字典的类似问题相同的方法,我只是在基于值合并时遇到问题。

4 个答案:

答案 0 :(得分:2)

这是使用sortedtoolz.unique的一种方式。我们的想法是按LEAVESQTY排序,然后按ORDERID删除重复项。

如果您无权访问toolz库,则逻辑与unique_everseen文档中的itertools recipe相同。

from operator import itemgetter
from toolz import unique

trades =  [{'ORDERID': 123, 'LEAVESQTY': 2200}, 
           {'ORDERID': 123, 'LEAVESQTY': 500}, 
           {'ORDERID': 456, 'LEAVESQTY': 100}, 
           {'ORDERID': 789, 'LEAVESQTY': 300}]

sorter = sorted(trades, key=itemgetter('LEAVESQTY'))
res = list(unique(sorter, key=itemgetter('ORDERID')))

print(res)

[{'LEAVESQTY': 100, 'ORDERID': 456},
 {'LEAVESQTY': 300, 'ORDERID': 789},
 {'LEAVESQTY': 500, 'ORDERID': 123}]

答案 1 :(得分:1)

使用简单的迭代。

<强>演示:

d = {}

trades =  [{'ORDERID': 123, 'LEAVESQTY': 2200}, 
            {'ORDERID': 123, 'LEAVESQTY': 500}, 
            {'ORDERID': 456, 'LEAVESQTY': 100}, 
            {'ORDERID': 789, 'LEAVESQTY': 300}]

for i in trades:
    if i['ORDERID'] not in d:
        d[i["ORDERID"]] = i
    else:
        if d[i["ORDERID"]]["LEAVESQTY"] > i["LEAVESQTY"]:
            d[i["ORDERID"]]["LEAVESQTY"] = i["LEAVESQTY"]
print(d.values())

<强>输出:

[{'ORDERID': 456, 'LEAVESQTY': 100}, {'ORDERID': 123, 'LEAVESQTY': 500}, {'ORDERID': 789, 'LEAVESQTY': 300}]

答案 2 :(得分:1)

您可以使用collections.defaultdict构建要列出映射的字典。

然后使用字典理解来计算每个列表的最小值。

from collections import defaultdict

trades =  [{'ORDERID': 123, 'LEAVESQTY': 2200}, 
           {'ORDERID': 123, 'LEAVESQTY': 500}, 
           {'ORDERID': 456, 'LEAVESQTY': 100}, 
           {'ORDERID': 789, 'LEAVESQTY': 300}]

d = defaultdict(list)

for item in trades:
    d[item['ORDERID']].append(item['LEAVESQTY'])

res = [{'ORDERID': k, 'LEAVESQTY': min(v)} for k, v in d.items()]

[{'LEAVESQTY': 500, 'ORDERID': 123},
 {'LEAVESQTY': 100, 'ORDERID': 456},
 {'LEAVESQTY': 300, 'ORDERID': 789}]

答案 3 :(得分:1)

您可以使用itertools.groupby()

from itertools import groupby

common = lambda x: x['ORDERID']

grouped = groupby(sorted(trades, key=common), key=common)

output = [min(group) for key, group in grouped]

output
#[{'LEAVESQTY': 500, 'ORDERID': 123},
# {'LEAVESQTY': 100, 'ORDERID': 456},
# {'LEAVESQTY': 300, 'ORDERID': 789}]

修改

排序是必要的,因为@jpp建议这样做,否则如果数据如下所示会产生重复的键:

#trades =  [{'ORDERID': 789, 'LEAVESQTY': 400},
#           {'ORDERID': 123, 'LEAVESQTY': 2200}, 
#            {'ORDERID': 123, 'LEAVESQTY': 500}, 
#            {'ORDERID': 456, 'LEAVESQTY': 100}, 
#            {'ORDERID': 789, 'LEAVESQTY': 300},
#            {'ORDERID': 789, 'LEAVESQTY': 150}]