qqc1037
qqc1037

Reputation: 85

Updating Pre-Existing Values in nested Dictionary with Loops

This query is somewhat of a follow up from my previous question: Creating Dictionaries from Lists inside of Dictionaries

which yielded me:

primaryDict = {'list_a':[{'apple':0}, {'orange':0}], 'list_b':[{'car':0}, {'bus':0}]}

to which I altered to the following for easier handling:

primaryDict = {'a': {'car': 0, 'bus': 0}, 'b': {'apple': 0, 'orange': 0}}

So the problem I have run into this time is that I need to update the numerical value for each occurrence of the string in the nested list given a set of conditions, being:

  1. In a separate list of sublists, example:

    objList = [['car', 'bus', 'train', 'apple', 'b'], ['apple', 'car', 'bike', 'a', 'b']]

in which lists of strings are nested, those are the sublists in which I'll be checking for an occurrence of the string.

  1. In order for the counter to go up, the corresponding string to the key must also be present in the same list. So, the counters in 'a':{} will only go up if both the string 'a' is present as well as the target string value inside 'a':{}.

So the resulting value for primaryDict['a'] and primaryDict['b'] should be:

{'car':1, 'bus':0}, {'apple':2, 'orange':0}

as 'car' appeared in the list with 'a', and 'bus' did not.

The attempt I tried to make for this problem was a mess of loops and if's akin to:

for k, v in primaryDict.items():
    for key in primaryDict:
        for sublist in objList:
            if key in sublist:
                for word in v:
                    if word in sublist:
                        primaryDict[key][v] = v.get(key, 0) + 1

which looks absolutely disgusting, does not work and clearly shows my lack of understanding of indexing.

My errors from various attempts mostly comprised of typeErrors where the dictionary I was referencing was clearly as string, meaning I was referencing the key or a value in a list, not the value in the nested dictionary.

Goal: I am to write a function that will loop over and update the numerical value in the nested Dictionary given the conditions (both key of primaryDict and nested dict present in sublist). I am trying NOT TO generate a new dictionary, and I am trying NOT TO rely on imported modules as I lack understanding of them, which will probably trip me up again in future.

Please advise me on how I should fix my code, and how I should index the numeric value properly if I wish to use the number for future calculations and comparisons.

Thanks

Upvotes: 3

Views: 757

Answers (3)

andrew_reece
andrew_reece

Reputation: 21284

First, split up the keys (k) and values (v) of primaryDict, using the .items() method.
Next, loop over each element in objList and check if each key (e.g. "a", "b") is included.
If so, then check if the keys of v (in other words, the specific objects like "car", "bus", etc) are also in the element of objList.
If so, add 1 to that object's count.

for k, v in primaryDict.items():
    for element in objList:
        if k in element:
            for obj in v:
                if obj in element:
                    v[obj] += 1

primaryDict 
{'a': {'bus': 0, 'car': 1}, 'b': {'apple': 2, 'orange': 0}}

Upvotes: 1

jpp
jpp

Reputation: 164843

One way is to iterate objList and use set methods to update the necessary values. The idea is to replace O(n) list comparisons with O(1) lookup for set.

primaryDict = {'a': {'car': 0, 'bus': 0},
               'b': {'apple': 0, 'orange': 0}}

objList = [['car', 'bus', 'train', 'apple', 'b'],
           ['apple', 'car', 'bike', 'a', 'b']]

for lst in objList:
    set_lst = set(lst)
    keys = set_lst & primaryDict.keys()
    values = set_lst - primaryDict.keys()
    for key in keys:
        for value in values & primaryDict[key].keys():
            primaryDict[key][value] += 1

print(primaryDict)        

{'a': {'car': 1, 'bus': 0}, 'b': {'apple': 2, 'orange': 0}}

Upvotes: 0

Nf4r
Nf4r

Reputation: 1410

Same as below, but more readable I think.

for key, values in primaryDict.items():
  for sublist in objList:
    if key in sublist:
      for element in sublist:
        if element in values:
          values[element] += 1

Upvotes: 0

Related Questions