Simos
Simos

Reputation: 23

More pythonic way for nested for loops

I have 2 for loops that are working but they're not too pythonic looking.

EDIT: I realized that oversimplified my example. I still need the values corresponding to the specific key.

The first one loops through a list of dictionaries and then through the keys and values of each dictionary and prints the value if the key equals to 'MATCH'.

The second one loops through the same list of dictionaries and a different dictionary. If a value in the first list of dictionaries is equal to the key of the second dictionary then it loops through the list of dictionaries again and prints the value if the key equals to 'MATCH'.

for item in data_dict:
    for k, v in item.items():
        if k == 'MATCH':
            print(v)


for item in data_dict:
    for k, v in item.items():
        for kx, vx in dictA.items():
            if v == kx:
                for k2, v2 in item.items():
                    if k2 == 'MATCH': 
                       print(v2)

Upvotes: 2

Views: 143

Answers (1)

Jean-François Fabre
Jean-François Fabre

Reputation: 140168

for item in data_dict:
    for k, v in item.items():
        if k == 'MATCH':
            print('found')

you're not using the dict properly, just using it as a list of tuples. Just write:

for item in data_dict:
    if 'MATCH' in item:
          print('found: ',item['MATCH'])
          # break here? not if you want multiple matches

same goes for the other loop. But I just reduced complexity from O(n**2) to O(n). You're still performing a linear search in a list of dictionaries, still not satisfactory.

The other way would be: create one dictionary with lists of your elements as the elements, instead of a list of dictionaries with elements.

That way you get all the info with 1 key lookup. Practical example:

Let's say your data looks like this:

list_of_dicts = [
{'MATCH':12, 'foo':14},
{'MATCH':5, 'bar':2},
{'what':0}
]

transform it as a dict of lists with collections.defaultdict(list):

import collections

dict_of_lists = collections.defaultdict(list)

for d in list_of_dicts:
    for k,v in d.items():
        dict_of_lists[k].append(v)

Let's look at the new dict:

>>> dict_of_lists
{'MATCH': [12, 5],
 'bar': [2],
 'foo': [14],
 'what': [0]}

once this is done, just get all the values matching a key with this:

if 'MATCH' in dict_of_lists:
    print(dict_of_lists['MATCH'])

which prints:

[12, 5]

The transformation done at the start must be done only once (or not at all if the data is properly organized from the start) to get super fast & easy data lookup.

Upvotes: 2

Related Questions