Search code examples
pythonfor-loopdictionarypython-itertools

Updating Values in Dictionary with for Loop of a List within a List


I know the logic/syntax of the code at the bottom of this post is off, but I'm having a hard time figuring out how I can write this to get the desired result. The first section creates this dictionary:

sco = {'human + big': 0, 'big + loud': 0, 'big + human': 0, 'human + loud': 0, 'loud + big': 0, 'loud + human': 0}

Then, my intention is to loop through each item in the dictionary "cnt" once for x and then loop through the dictionary a second time for x each time the item has the same value as (cnt[x][1]) but a different key (cnt[x][0]), creating a string that will match the format "%s + %s" found in the dictionary "sco." It should then find the key in sco that matches the key assigned to the variable dnt and increment the value for that key in sco by 1.

# -*- coding: utf-8 -*-

import itertools
sho = ('human', 'loud', 'big')
sco = {}
for a,b in itertools.permutations(sho, 2):
    sco["{0} + {1}".format(a,b)] = 0

cnt = [('human', 'ron g.'), ('loud', 'ron g.'), ('big', 'kim p.'), ('human', 'kim p.'), ('loud', 'brian a.'), ('human', 'linda m.'), ('loud', 'linda m.')]
for x in cnt:
    upd = cnt[x][0]
    who = cnt[x][1]
    for x in cnt:
        if cnt[x][0] != upd and cnt[x][1] == who:
            cpg = cnt[x][0]
            dnt = '%s + %s' % (upd, cpg)
            for i in sco:
                if sco[i][0] == dnt:
                    sco[i][1] += sco[i][1]
print sco

Currently, printing sco results in no change to any of the values. The desired outcome of the code is this:

{'human + big': 1, 'big + loud': 0, 'big + human': 1, 'human + loud': 2, 'loud + big': 0, 'loud + human': 2}

Any help is greatly appreciated!

The revised code is this:

# -*- coding: utf-8 -*-

import itertools
sho = ('human', 'loud', 'big')
sco = {}
for a,b in itertools.permutations(sho, 2):
    sco["{0} + {1}".format(a,b)] = 0

cnt = [('human', 'ron g.'), ('loud', 'ron g.'), ('big', 'kim p.'), ('human', 'kim p.'), ('loud', 'brian a.'), ('human', 'linda m.'), ('loud', 'linda m.')]
for x in cnt:
    upd = cnt[0]
    who = cnt[1]
    for x in cnt:
        if cnt[0] != upd and cnt[1] == who:
            cpg = cnt[0]
            dnt = '%s + %s' % (upd, cpg)
            sco[dnt] += 1
print sco

The following code does what I intended. Thank you to @dermen & @abarnert:

# -*- coding: utf-8 -*-

import itertools
sho = ('human', 'loud', 'big')
sco = {}
for a,b in itertools.permutations(sho, 2):
    sco["{0} + {1}".format(a,b)] = 0

cnt = [('human', 'ron g.'), ('loud', 'ron g.'), ('big', 'kim p.'), ('human', 'kim p.'), ('loud', 'brian a.'), ('human', 'linda m.'), ('loud', 'linda m.')]
for x in cnt:
    upd = x[0]
    who = x[1]
    for x in cnt:
        if x[0] != upd and x[1] == who:
            cpg = x[0]
            dnt = '%s + %s' % (upd, cpg)
            sco[dnt] += 1
print sco

Solution

  • The actual problem is that, instead of adding 1 to the values, you're doubling them:

    sco[i][1] += sco[i][1]
    

    And no matter how many times you add 0 to 0, it's still 0.

    To add 1, just use += 1.


    But you've got another problem, at least in the code you posted. Each sco[i] value just a number, not a list of two things, the second of which is a number. So what you really want is:

    sco[i] += 1
    

    And similarly, the keys aren't sco[i][0], they're just i.


    And you've got a third problem. This one doesn't actually break your code, it just makes it more complicated, harder to understand, and slower… but that's still worth fixing.

    The whole point of dictionaries is that you don't have to iterate them to search for a key, you just look up the key directly. So, instead of this:

    for i in sco:
        if i == dnt:
            sco[i] += 1
    

    … just do this:

    sco[dnt] += 1
    

    It's simpler, harder to get wrong, and more efficient, all at the same time.


    I can't promise there are no other errors in your code, but you definitely need to fix these three, on top of whatever else is wrong, and I'm pretty sure the first one is the one that happens to be causing the specific problem you asked about.