问题
I'm trying to find the keys for the matching values in a dictionary. But to get any kind of valid match I need to truncate the values in the lists.
I want to truncate down the the tenths spot (e.g. "2.21" to "2.2").
dict1 = {'red':[1.98,2.95,3.83],'blue':[2.21,3.23,4.2333],'orange':[3.14,4.1,5.22]}
dict2 = {'green':[3.11,4.12,5.2],'yellow':[2.2,3.2,4.2],'red':[5,2,6]}
matches = []
for key1 in dict1:
for key2 in dict2:
if dict1[key1] == dict2[key2]:
matches.append((key1, key2))
print(matches)
I'm trying to get "green"
and "orange"
should be a match, as well as "blue"
and "yellow"
. But I'm not sure if I need to parse through each value list first, make the changes, and then continue. If I could make the changes in the comparison itself that would be ideal.
回答1:
You can use zip
on the lists and compare values, but you should set a tolerance tol
for which a pair of values from two list will be considered the same:
dict1 = {'red':[1.98,2.95,3.83],'blue':[2.21,3.23,4.2333],'orange':[3.14,4.1,5.22]}
dict2 = {'green':[3.11,4.12,5.2],'yellow':[2.2,3.2,4.2],'red':[5,2,6]}
matches = []
tol = 0.1 # change the tolerance to make comparison more/less strict
for k1 in dict1:
for k2 in dict2:
if len(dict1[k1]) != len(dict2[k2]):
continue
if all(abs(i-j) < tol for i, j in zip(dict1[k1], dict2[k2])):
matches.append((k1, k2))
print(matches)
# [('blue', 'yellow'), ('orange', 'green')]
If your list lengths will always be the same, you can remove the part where non matching lengths are skipped.
回答2:
d = {'green': [3.11, 4.12, 5.2]}
>>> map(int, d['green'])
[3, 4, 5]
You need to map the list items to integers before you compare
for key2 in dict2:
if map(int, dict1[key1]) == map(int, dict2[key2]):
matches.append((key1, key2))
I'm assuming you want to round down. If you want to round to the nearest integer use round
instead of int
回答3:
If all you care about is truncation, and not actual rounding, you could convert the values to a string and slice off the excess:
for key1 in dict1:
for key2 in dict2:
# I'm pulling these values out so you can look at them:
a = str(dict1[key1])
b = str(dict1[key2])
# find the decimal and slice it off
if a[:a.index('.')] == b[:b.index('.')]:
matches.append((key1, key2))
If you want to actually round, use the built-in round(float, digits)
(https://docs.python.org/2/library/functions.html):
for key1 in dict1:
for key2 in dict2:
if round(dict1[key1],0) == round(dict2[key2], 0):
matches.append((key1, key2))
(Also, watch your indentations!)
回答4:
You can add some list comprehensions in between your loops to convert the floats to integers, like this:
dict1 = {'red':[1.98,2.95,3.83],'blue':[2.21,3.23,4.2333],'orange':[3.14,4.1,5.22]}
dict2 = {'green':[3.11,4.12,5.2],'yellow':[2.2,3.2,4.2],'red':[5,2,6]}
matches = []
for key1 in dict1:
for key2 in dict2:
dict1[key1] = [int(i) for i in dict1[key1]]
dict2[key2] = [int(i) for i in dict2[key2]]
if dict1[key1] == dict2[key2]:
matches.append((key1, key2))
print(matches)
Output:
[('blue', 'yellow'), ('orange', 'green')]
I hope this helps :)
来源:https://stackoverflow.com/questions/38077634/truncate-dictionary-list-values