Steven Marquez
Steven Marquez

Reputation: 21

Count instances of a value in a certain index of sublists within a list, but only once per list

I have data similar to this:

[[1, 1, 4]], [[1, 2, 4], [1, 7, 4]], [[2, 2, 4]]

I am iterating like this:

count = 0
for list in lists:
    for sublist in list:
        if sublist[2] == 4:
            count += 1
print(count)

The output always ends up being 4.

I want to iterate through all 3 lists of sublists, count the time that "4" is in the third index of a sublist. However, in the second list I only want it counted once, not twice. So the value returned should be 3, not 4.

Upvotes: 2

Views: 102

Answers (2)

MSeifert
MSeifert

Reputation: 152637

You can simply fix it by breaking out of the innermost loop if you found one sublist that has a 4 in the third position. That basically checks if any sublist fulfills your condition:

count = 0
for lst in lists:
    for sublist in lst:
        if sublist[2] == 4:
            count += 1
            break             # just added that line
print(count)
# 3

I also replaced the variable name list with lst because it would otherwise shadow the built-in name list.

This could also be written as:

>>> sum(any(sublist[2] == 4 for sublist in lst) for lst in lists)
3

Or in case you want to check that all sublists fulfill the condition replace any with all:

>>> sum(all(sublist[2] == 4 for sublist in lst) for lst in lists)
3

Upvotes: 1

John Zwinck
John Zwinck

Reputation: 249133

def has4(lol):
   for lst in lol:
       if lst[2] == 4:
           return True
   return False

lists = [[1, 1, 4]], [[1, 2, 4], [1, 7, 4]], [[2, 2, 4]]

count = sum(map(has4, lists))

First we define a predicate which returns True for matched items. Then we use map() to transform the input into a boolean sequence of matched/not-matched. Then we sum, taking advantage of the fact that True counts as 1 and False is 0.

Upvotes: 0

Related Questions