Python根据值从字典列表中删除重复项

Python Remove duplicates from list of dictionaries based on a value

我有字典清单

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
vals = [
         {'tmpl_id': 67,  'qty_available': -3.0, 'product_id': 72, 'product_qty': 1.0},    
         {'tmpl_id': 67,  'qty_available': 5.0, 'product_id': 71, 'product_qty': 1.0}
         {'tmpl_id': 69,  'qty_available': 10.0, 'product_id': 74, 'product_qty': 1.0}
       ]

from operator import itemgetter
getvals = operator.itemgetter('tmpl_id')

val.sort(key=getvals)

result = []

for k, g in itertools.groupby(val, getvals):

    result.append(g.next())

val[:] = result

我想删除重复值(tmpl_id),并且基于可用数量,可用数量小于或等于负。

输出如下:

1
2
3
4
vals = [
          {'tmpl_id': 67,  'qty_available': 5.0, 'product_id': 71, 'product_qty': 1.0}
          {'tmpl_id': 69,  'qty_available': 10.0, 'product_id': 74, 'product_qty': 1.0}
       ]


您可以使用"tmpl_id"的值作为键来存储dict,将dict设置为值,如果您得到的dict具有更高的'qty_available',则用当前dict替换:

1
2
3
4
5
6
7
8
9
10
11
def remove_dupes(l, k, k2):
    seen = {}
    for d in vals:
        v, v2 = d[k], d[k2]
        if v not in seen:
            seen[v] = d
        elif v2 > seen[v][k2]:
            seen[v] = d
    return seen

vals[:] = remove_dupes(vals,"tmpl_id",'qty_available' ).values()

输出:

1
2
[{'product_id': 71, 'qty_available': 5.0, 'tmpl_id': 67, 'product_qty': 1.0},
{'product_id': 74, 'qty_available': 10.0, 'tmpl_id': 69, 'product_qty': 1.0}]

如果要使用sorted和groupby,只需反向排序并从每个v中获取第一个值:

1
2
3
4
5
6
7
8
9
from itertools import groupby
from operator import itemgetter

keys = itemgetter("tmpl_id",'qty_available')

vals[:] = (next(v) for k,v in groupby(sorted(vals, key=keys,reverse=True),
                 key=itemgetter("tmpl_id")))

print(vals)

颠倒排序将意味着较高的'qty_available'将首先出现,因此对于唯一的dict,它将只给您该dict,对于重复的tmpl_id,您将得到一个最大值为"可用数量"的dict。

如果您希望使用就地排序而不是创建新的列表,只需使用vals.sort()并删除对排序的调用


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
from collections import Counter

vals = [{'tmpl_id': 67,  'qty_available': -3.0, 'product_id': 72, 'product_qty': 1.0},
        {'tmpl_id': 67,  'qty_available': 5.0, 'product_id': 71, 'product_qty': 1.0},
        {'tmpl_id': 69,  'qty_available': 10.0, 'product_id': 74, 'product_qty': 1.0},]

k = [x['tmpl_id'] for x in vals]

new_vals=[]

for i in Counter(k):
    all = [x for x in vals if x['tmpl_id']==i]
    new_vals.append(max(all, key=lambda x: x['qty_available']))

>>> new_vals
[
    {'product_qty': 1.0, 'qty_available': 5.0, 'tmpl_id': 67, 'product_id': 71},
    {'product_qty': 1.0, 'qty_available': 10.0, 'tmpl_id': 69, 'product_id': 74}
]