2015-04-08 3 views
-2

У меня есть два словаря:Сравнение словаря ключей с допусками

d1 = {'100.1125': '353.2216'; '151.0977': '131.2193'; '102.0553': '103.6859'; '103.0209': '104.624'} 

d2 = {'100.1124': '352.2220'; '200': '131.2193'; '300': '103.6859'; '400': '104.624'; '103.0545': '448.3161'} 

я желаю перебрать ключей в d1 и проверить их наличие в d2, +/- заданный допуск. Если true, я хочу затем сравнить связанные значения для каждого словарного ключа и проверить, соответствуют ли они также и данному допуску. Если найдено совпадение, я хотел бы написать вывод в один файл (Output_match.txt). Если совпадение не найдено, я хотел бы написать ключ d1 и связанное значение со вторым файлом (Output_nomatch.txt).

Итак, допустим, допуск для сравнения словарных ключей составляет +/- 0.0002. Допуск для сравнения значений - +/- 5.

я ожидал бы Output_match.txt содержать:

key ---- value 
100.1125 ---- 353.2216 

Я ожидал бы Output_nomatch.txt содержать:

key ---- value 
151.0977 ---- 131.2193 
102.0553 ---- 103.6859 
103.0209 ---- 104.624 

Может кто-нибудь предложить любую помощь здесь?

EDIT:

Извиняюсь за то, что не предоставил мою текущую попытку:

with open(os.path.join(path,'out_true.txt'), 'w') as opt_true, open(os.path.join(path,'out_false.txt'), 'w') as opt_false: 
header = ('%s\t%s\t%s\t%s\n') % ('file1_mz', 'file1_rt', 'file2_mz', 'file2_rt') 
opt_true.write(header) 
for key in d1.keys(): 
    upper_mz = float(key) + (float(key) * (ppm*0.000001)) 
    lower_mz = float(key) - (float(key) * (ppm*0.000001)) 
    upper_rt = float(dict1[key]) + (2*rt_shift) 
    lower_rt = float(dict1[key]) - (2*rt_shift) 
    for key2 in d2: 
     upper_mz2 = float(key2) + (float(key2) * (ppm*0.000001)) 
     lower_mz2 = float(key2) - (float(key2) * (ppm*0.000001)) 
     upper_rt2 = float(dict2[key2]) + (2*rt_shift) 
     lower_rt2 = float(dict2[key2]) - (2*rt_shift) 
     if float(upper_mz) >= float(lower_mz2) and float(lower_mz) <= float(upper_mz2) and float(upper_rt) >= float(lower_rt2) and float(lower_rt) <= float(upper_rt2): 
      opt_true.write(('%s\t%s\t%s\t%s\n') % (str(key), str(dict1[key]), str(key2), str(dict2[key2]))) 
      #print float(key) 
      a[key] = d1[key] 
      b[key2] = d2[key2] 
for key in d1.keys(): 
    if not key in a: 
     opt_false.write(('%s\t%s\n') % (str(key), d1[key])) 
for key2 in d2.keys(): 
    if not key2 in b: 
     opt_false.write(('%s\t%s\n') % (str(key), d1[key])) 

opt_true.close() 
opt_false.close() 
+1

Это не учебное пособие; где ваша реализация и в чем именно проблема? – jonrsharpe

+1

Что делать, если имеется несколько совпадений для одного и того же ключа? Если ключ & значение из 'd1' записывается в' Output_match.txt' более одного раза? например для допуска 0,1, ключа 'd1 = 100.0' и ключей' 100.01' и '99.99' в' d2', ключ из 'd1' будет выводиться дважды. – mhawke

+0

@mhawke вы абсолютно правы, и я должен был указать эту возможность в своем оригинальном посте. Возможно, что некоторые клавиши в d1 перекрывают несколько клавиш в d2. – MRJ

ответ

1

Вы могли бы попробовать что-то вроде этого, используя встроенную функцию abs, для того, чтобы вычислить расстояние в простой путь:

d1 = {'100.1125': '353.2216', '151.0977': '131.2193', 
     '102.0553': '103.6859', '103.0209': '104.624'} 
d2 = {'100.1124': '352.2220', '200': '131.2193', 
     '300': '103.6859', '400': '104.624', '103.0545': '448.3161'} 

key_tolerance, value_tolerance = 0.0002, 5 
output_match, output_nomatch = [], [] 

for i, j in d1.items(): 
    for k, l in d2.items(): 
     if (abs(float(i)-float(k)) <= key_tolerance and 
      abs(float(j)-float(l)) <= value_tolerance): 
      output_match.append((i, j)) 
     else: 
      output_nomatch.append((i, j)) 

print(output_match, '----', set(output_nomatch) - set(output_match), sep='\n') 

Выход:

[('100.1125', '353.2216')] 
---- 
{('102.0553', '103.6859'), 
('103.0209', '104.624'), 
('151.0977', '131.2193')} 
Смежные вопросы