2017-02-11 3 views
0

У меня есть список словарей, таких как:Оптимальный алгоритм для сравнения двух словарей в Python 3

Stock=[ 
{'ID':1,'color':'red','size':'L','material':'cotton','weight':100,'length':300,'location':'China'}, 
{'ID':2,'color':'green','size':'M','material':'cotton','weight':200,'length':300,'location':'China'}, 
{'ID':3,'color':'blue','size':'L','material':'cotton','weight':100,'length':300,'location':'China'} 
] 

И другой список словарей, таких как:

Prices=[ 
{'color':'red','size':'L','material':'cotton','weight':100,'length':300,'location':'China'} 
{'color':'blue','size':'S','weight':500,'length':150,'location':'USA', 'cost':1$} 
{'color':'pink','size':'L','material':'cotton','location':'China','cost':5$}, 
{'cost':5$,'color':'blue','size':'L','material':'silk','weight':100,'length':300} 
] 

Так что мне нужно найти «стоимость» для каждой записи в Stock от Prices. Но может быть ситуация, когда я не нахожу 100% совпадений элементов dict, и в этом случае мне нужен самый похожий элемент и получить его «стоимость».

output=[{'ID':1,'cost':1$},{'ID':2,'cost':5$},...] 

Пожалуйста, подскажите оптимальное решение для этой задачи. Я думаю, что это похоже на Loop от наивысшего до самого низкого соответствия, когда мы пытаемся найти запись с максимальным совпадением, а если не нашли - попробуйте выполнить меньшее условие соответствия.

+0

Stion. Для данного входа (акции и цены), какой должен быть желаемый результат? – ppasler

ответ

-1

это напоминает мне о нечетких или нейронных сетевых решений, [на python2]

в любом случае, здесь решение Numpy,:

Stock=[ 
{'ID':1,'color':'red','size':'L','material':'cotton','weight':100,'length':300,'location':'China'}, 
{'ID':2,'color':'green','size':'M','material':'cotton','weight':200,'length':300,'location':'China'}, 
{'ID':3,'color':'blue','size':'L','material':'cotton','weight':100,'length':300,'location':'China'} 
] 

Prices=[ 
{'color':'red','size':'L','material':'cotton','weight':100,'length':300,'location':'China'}, 
{'cost':2,'color':'blue','size':'S','weight':500,'length':150,'location':'USA'}, 
{'cost':5,'color':'pink','size':'L','material':'cotton','location':'China'}, 
{'cost':15,'color':'blue','size':'L','material':'silk','weight':100,'length':300} 
] 

import numpy as np 

# replace non useful records. 
for p in Prices: 
    if not(p.has_key('cost')): 
     Prices.remove(p) 

def numerize(lst_of_dics): 
    r=[] 
    for d in lst_of_dics: 
     r1=[] 
     for n in ['color','size','material','weight','length','location']: 
      try: 
       if n=='color': 
        # it is 0s if unknown 
        # only 3 letters, should work ,bug!!! 
        z=[0,0,0] 
        r1+=[ord(d[n][0]),ord(d[n][1]),ord(d[n][2])] 
       elif n=='size': 
        z=[0,0,0] 
        r1+=[ord(d[n])]*3 
       elif n=='material': 
        z=[0,0,0] 
        r1+=[ord(d[n][0]),ord(d[n][1]),ord(d[n][2])] 
       elif n=='location': 
        z=[0,0,0] 
        r1+=[ord(d[n][0]),ord(d[n][1]),ord(d[n][2])] 
       else: 
        z=[0,0,0] 
        r1+=[d[n]]*3 
      except: 
       r1+=z 

     r.append(r1) 
    return r 

St = numerize(Stock) 
Pr = np.array(numerize(Prices)) 

output=[] 
for i,s in enumerate(St): 
    s0 = np.reshape(s*Pr.shape[0],Pr.shape) 
    # stage 0: make one element array to subtract easily 
    s1 = abs(Pr -s0) 
    # abs diff 
    s2 = s1 * Pr.astype('bool') * s0.astype('bool') 
    # non-extentent does'nt mean match.. 
    s21 = np.logical_not(Pr.astype('bool') * s0.astype('bool'))*25    
    s2 = s2+s21 
    # ignore the zero fields..(non-extentse) 
    s3 = np.sum(s2,1) 
    # take the smallest 
    s4 = np.where(s3==np.min(s3))[0][0] 
    c = Prices[s4]['cost'] 
    #print c,i 
    output.append({'ID':i+1 ,'cost':c}) 

print(output) 

, что дает мне следующие результаты (со многими предположения):

[{'cost': 15, 'ID': 1}, {'cost': 5, 'ID': 2}, {'cost': 15, 'ID': 3}] 

Обратите внимание, что это правильный результат сравнения на основе Значения и виды свойств

угодить на голосование и проверить ответ, если он удовлетворяет вас ..

0

как об этом

Stock=[ 
{'ID':1,'color':'red','size':'L','material':'cotton','weight':100,'length':300,'location':'China'}, 
{'ID':2,'color':'green','size':'M','material':'cotton','weight':200,'length':300,'location':'China'}, 
{'ID':3,'color':'blue','size':'L','material':'cotton','weight':100,'length':300,'location':'China'} 
] 

Prices=[ 
{'color':'red','size':'L','material':'cotton','weight':100,'length':300,'location':'China'}, 
{'cost':'2$','color':'blue','size':'S','weight':500,'length':150,'location':'USA'}, 
{'cost':'5$','color':'pink','size':'L','material':'cotton','location':'China'}, 
{'cost':'15$','color':'blue','size':'L','material':'silk','weight':100,'length':300} 
] 

Prices = [p for p in Prices if "cost" in p] #make sure that everything have a 'cost' 
result = [] 
for s in Stock: 
    field = set(s.items()) 
    best_match = max(Prices, key=lambda p: len(field.intersection(p.items())), default=None) 
    if best_match: 
     result.append({"ID":s["ID"], "cost":best_match["cost"] }) 
print(result) 
#[{'ID': 1, 'cost': '5$'}, {'ID': 2, 'cost': '5$'}, {'ID': 3, 'cost': '15$'}] 

найти наиболее похожую запись я первый преобразовать Dict в a set, затем используйте max, чтобы найти самый большой intersection цены с запасом, который я проверяю, используя функцию лямбда для ключа max

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