pythonbeginner44
pythonbeginner44

Reputation: 11

For loop that won't save values of counter

I'm trying to count the number of occurrences of each string in my nested list (it it much larger on my computer, below is a sample to demonstrate the structure)

lst = [[545300, ['sub10', 'sub13']], [546636, ['sub15', 'sub17']], [546648, ['sub15', 'sub17']], [8775, ['sub14', 'sub17']], [65, ['sub11', 'sub14']]]

sh1 = 0
sh2 = 0
sh3 = 0
sh4 = 0
sh5 = 0
sh6 = 0
sh7 = 0
sh8 = 0

for pos, sampleList in lst: 
    if 'sub10' in sampleList: 
        sh1 += 1
    elif 'sub11' in sampleList: 
        sh2 += 1
    elif 'sub12' in sampleList: 
        sh3 += 1
    elif 'sub13' in sampleList: 
        sh4 += 1
    elif 'sub14' in sampleList: 
        sh5 += 1
    elif 'sub15' in sampleList: 
        sh6 += 1
    elif 'sub16' in sampleList: 
        sh7 += 1
    elif 'sub17' in sampleList: 
        sh8 += 1

End goal:

sub10 sub11 sub12 sub13 sub14 sub15 sub16 sub17
1 1 0 1 2 2 0 2

The issue is that the value for 'sub17' always comes up as 0, even though I can see many instances of 'sub17' in the list when I print it. All other counters are working fine, it's just the last "elif" that won't work.

I've also tried:

for pos, sampleList in lst: 
    if 'sub10' in sampleList: 
        sh1 += 1
    elif 'sub11' in sampleList: 
        sh2 += 1
    elif 'sub12' in sampleList: 
        sh3 += 1
    elif 'sub13' in sampleList: 
        sh4 += 1
    elif 'sub14' in sampleList: 
        sh5 += 1
    elif 'sub15' in sampleList: 
        sh6 += 1
    elif 'sub16' in sampleList: 
        sh7 += 1
    else: 
        sh8 += 1

I feel like the answer is probably something obvious and I just need a fresh (or more advanced) set of eyes to look over it.

Upvotes: 0

Views: 124

Answers (4)

Jab
Jab

Reputation: 27515

Using collections.Counter:

from collections import Counter

res = Counter(sum(dict(lst).values(), []))
print(dict(res))

{'sub17': 3, 'sub15': 2, 'sub14': 2, 'sub10': 1, 'sub13': 1, 'sub11': 1}

Without collections.Counter:

vals = sum(dict(lst).values(), [])
res = dict.fromkeys(vals, 0) 
for val in vals:
    res[val] += 1
print(res)

{'sub17': 3, 'sub15': 2, 'sub14': 2, 'sub10': 1, 'sub13': 1, 'sub11': 1}

Upvotes: 3

tdelaney
tdelaney

Reputation: 77407

You can use collections.Counter to count the values. Instead of a complicated set of getters and iterators, just use a simple for loop.

import collections

lst = [[545300, ['sub10', 'sub13']], [546636, ['sub15', 'sub17']], [546648, ['sub15', 'sub17']], [8775, ['sub14', 'sub17']], [65, ['sub11', 'sub14']]]

counts = collections.Counter()
for _, vals in lst:
    counts.update(vals)

Upvotes: 1

pho
pho

Reputation: 25490

Use a dictionary, where keys are the string you're counting, and values are the count.

counts = {}
for pos, sampleList in lst: 
    for item in sampleList:
        # .get() returns the value at counts[item], and 0 if none exists
        # Then you increment this and save it to counts[item]
        counts[item] = counts.get(item, 0) + 1 

This way, you don't have to hardcode all the if statements, and you don't have a mess of variables to deal with.

With your example lst, the value of counts is:

{'sub10': 1, 'sub13': 1, 'sub15': 2, 'sub17': 3, 'sub14': 2, 'sub11': 1}

To access the count of a given string, you can use .get() again:

print(counts.get("sub17", 0)) # Gives 3
print(counts.get("sub12", 0)) # Gives 0

Upvotes: 1

Caldazar
Caldazar

Reputation: 3802

Don't use elif:

lst = [[545300, ['sub10', 'sub13']], [546636, ['sub15', 'sub17']], [546648, ['sub15', 'sub17']], [8775, ['sub14', 'sub17']], [65, ['sub11', 'sub14']]]

sh1 = 0 
sh2 = 0 
sh3 = 0 
sh4 = 0 
sh5 = 0 
sh6 = 0 
sh7 = 0 
sh8 = 0

for pos, sampleList in lst: 
    if 'sub10' in sampleList: 
        sh1 += 1
    if 'sub11' in sampleList: 
        sh2 += 1
    if 'sub12' in sampleList: 
        sh3 += 1
    if 'sub13' in sampleList: 
        sh4 += 1
    if 'sub14' in sampleList: 
        sh5 += 1
    if 'sub15' in sampleList: 
        sh6 += 1
    if 'sub16' in sampleList: 
        sh7 += 1
    if 'sub17' in sampleList: 
        sh8 += 1

By using elif, you just check for the smallest value that appears (since you ordered them that way), and sub17 is always in the second position in your example.

Upvotes: -1

Related Questions