Reputation: 207
Trying to match key, values in dictionaries with nested list elements
dict = {'a':[1, 5], 'c':[7, 9], 'f':[10, 12], 'b':[15, 20]}
list_A = [['a', '4'], ['a', '7'], ['b', '17'], ['b', 10], ['c', '7'], ['d', '7'], ['f', '11'], ['f', '12']]
list_A_no_reps =['a', 'b', 'c', 'd', 'f']
I am trying to get a list which has the values that match with list_A and dict i.e. as in the values of list a ( the second elements in the nested lists) should lie between the value list pair of the dict.
match_list = [['a', '4'], ['b', '17'], ['c', '7'], ['f', '11'], ['f', '12']]
I am trying to first match the keys of dict with list_A_no_reps and if there is a match, I am trying to find out if it lies between the values of each key, value pair. I have this so far:
g = []
for key, values in dict.items():
for element in list_A_no_rep:
if key == element:
for cord in list_A:
if (values[0] <= int(cord[1]) <= values[2]):
g.append(cord)
Upvotes: 1
Views: 3939
Reputation: 2320
d = {'a':[1, 5], 'c':[7, 9], 'f':[10, 12], 'b':[15, 20]}
li = [['a', '4'], ['a', '7'], ['b', '17'], ['b', 10], ['c', '7'], ['d', '7'], ['f', '11'], ['f', '12']]
It would be quicker to look up a key in d
for each set of values in li
than iterate through the list for each key in d
. This can be done in a single line with a list comprehension:
match_li = [v for v in li if v[0] in d and d[v[0]][0] <= int(v[1]) <= d[v[0]][2]]
yields
[['a', '4'], ['b', '17'], ['c', '7'], ['f', '11'], ['f', '12']]
Upvotes: 0
Reputation: 180411
I would group the sublists in a dict by the first element which is the letter then iterate over your original dict and check if each key is in the grouping dict and do your comparison.
d = {'a': [1, 5], 'c': [7, 9], 'f': [10, 12], 'b': [15, 20]}
list_A = [['a', '4'], ['a', '7'], ['b', '17'], ['b', 10], ['c', '7'], ['d', '7'], ['f', '11'], ['f', '12']]
from collections import defaultdict
d2 = defaultdict(list)
for k,v in list_A:
d2[k].append(v)
out = []
for k, v in d.items():
if k in d2:
vals = d2[k]
for v2 in vals:
if v[0] <= int(v2) <= v[1]:
out.append([k,v2])
print(out)
['a', '4'], ['c', '7'], ['b', '17'], ['f', '11'], ['f', '12']]
Or use viewkeys to get the common keys:
out = []
for k in d.viewkeys() & d2.viewkeys():
vals, v = d2[k], d[k]
for v2 in vals:
if v[0] <= int(v2) <= v[1]:
out.append([k,v2])
Or just loop over listA:
d = {'a': [1, 5], 'c': [7, 9], 'f': [10, 12], 'b': [15, 20]}
list_A = [['a', '4'], ['a', '7'], ['b', '17'], ['b', 10], ['c', '7'], ['d', '7'], ['f', '11'], ['f', '12']]
out = []
for sub in list_A:
k, val = sub
if k in d:
v = d[k]
if v[0] <= int(val) <= v[1]:
out.append(sub)
print(out)
[['a', '4'], ['b', '17'], ['c', '7'], ['f', '11'], ['f', '12']]
Upvotes: 1
Reputation: 3223
You can try:
g = []
for key, values in dict.items():
if key in list_A_no_rep:
for cord in list_A:
if ( cord[0] == key ):
if (values[0] <= int(cord[1]) <= values[1]):
g.append(cord)
print g
Output:
[['a', '4'], ['c', '7'], ['b', '17'], ['f', '11'], ['f', '12']]
Modification in your code:
g = []
for key, values in dict.items():
for element in list_A_no_rep:
if key == element:
for cord in list_A:
if ( cord[0] == element ): #line added
if (values[0] <= int(cord[1]) <= values[1]):
g.append(cord)
The problem in your code was that you were checking with all other elements of list_A
too. Therefore you would be getting the undesired value which might come within the range of some another key's range. So a if condition is required to check if a valid comparison with same key is occurring.
For example, without if condition you would have checked ['a','7']
with c:[7,9]
. Hence you would have included it in g
even though it does not satisfy the range specified for a
.
Upvotes: 2
Reputation: 1769
Update
Change values[2]
to values[1]
As your dictionary has two elements and indexing is zero based, so [1, 5]
would result in values[0] == 1 and values[1] == 5
Also you might like to go for a better solution, by leaving out list_A_no_reps
and removing the if key == element
block, then using cord[0]
to compare.
Upvotes: 0