Reputation: 11
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
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
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
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
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