2015-12-08 2 views
2

У меня есть список словарейPython Удаление дубликатов из списка словарей на основе значения

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), а также на основе qty_available меньше или отрицательное

Выходной сигнал будет быть как:

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} 
     ] 
+0

Вы должны показать, что вы попробовали и сказать, где вы сейчас застряли. Люди помогут вам больше, если вы сможете показать свои собственные усилия ... –

+0

Читайте это: http://stackoverflow.com/questions/1165352/calculate-difference-in-keys-contained-in-two-python-dictionaries – Idos

+0

Is данные в порядке «qty_available»: '? –

ответ

0
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} 
] 
1

Вы можете хранить dicts используя значение от "tmpl_id" как задающего Dict в качестве значения, если вы получаете Dict с более высокой 'qty_available' то замените текущий Словаре ключ:

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() 

Выход:

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

, если бы вы были использовать отсортированный и GroupBy, вам просто нужно сортировать в обратном порядке и получить первое значение из каждого V:

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' придет фи поэтому для уникальных dicts он просто даст вам этот dict, для повторения tmpl_id вы получите тот, у которого наибольшее значение для qty_available'`.

Если вы хотите, чтобы Inplace рода вместо создания нового списка просто использовать vals.sort() и удалить вызов сортированные

Смежные вопросы