1

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)

4 Answers 4

2

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.

Sign up to request clarification or add additional context in comments.

Comments

1

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']]

Comments

0

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.

Comments

0
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']]

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.