Andrea P
Andrea P

Reputation: 39

Python - count occurrences in list of list

I'm new to python, I'm therefore sorry if this question might be stupid. I have a list of lists that looks like this:

a = [['P - tag1', 'A - tag2', 'P - tag2', ' B - tag1', 'P - tag3'],['A - tag2', 'B - tag1'],['P - tag2', 'B - tag1','P - tag 3]]

What I want to do is count the number of lists that have at least one element that contain the string 'P -'. In this example the answer would be 2.

Then I would also like to count the lists that have n number of elements containing the 'P -' string. Let's say I want to know how many lists have 2 'P -' elements (1 in the given example). What would be the easiest and more efficient way to achieve this?

Upvotes: 2

Views: 469

Answers (7)

VanTan
VanTan

Reputation: 657

sum(x > 0 for x in [sum([1 for s in i if s.startswith("P -")]) for i in a])

change x > 0 to x > i to count other occurrence rates.

How does this work?

[1 for s in i if s.startswith("P -")] returns 1 for every string that begins with P -

Sum function and [] surrounding it will then return a list with count of those strings

finally outer sum will get you your desired output.

This should answer both of your questions!

Upvotes: 0

Risadinha
Risadinha

Reputation: 16666

It sounds like you want to group the lists in your list by occurrence of 'P -':

>>> a = [['P - tag1', 'A - tag2', 'P - tag2', ' B - tag1', 'P - tag3'],['A - tag2', 'B - tag1'],['P - tag2', 'B - tag1','P - tag 3']]
>>> res = [(f'list{i}', sum(1 for j in l if 'P -' in j)) for i,l in enumerate(a, start=1)]
>>> res
[('list1', 3), ('list2', 0), ('list3', 2)]
>>> sum(1 for i in res if i[1] > 0)
2

res contains the count of the occurrences per list, and the sum of 2 is the result of counting all lists that contain at least 1 occurrence. Counting all occurrences in all lists would be sum(i[1] for i in res).

Upvotes: 0

mad_
mad_

Reputation: 8273

Just look for pattern 'P -tag' in the inner list converted to string without iterating over the entire inner list.

sum([1 for i in a if 'P - tag' in ''.join(i)])

Upvotes: 0

zipa
zipa

Reputation: 27869

This will do it, its a list comprehension that will check if sublist has at least n elements that contain P -:

 n = 1
 len([i for i in a if len([j for j in i if 'P -' in j])>=n])

You just change n to specify bottom limit.

Upvotes: 1

Thijs van Ede
Thijs van Ede

Reputation: 917

I have already seen some nice answers here, however, here is also an explanation of why these work.

Explanation

Lets break this question down, first lets take a look at how we can see if a string contains P -:

string_a = 'P - tag1'
string_b = 'A - tag2'

'P -' in string_a # yields True
'P -' in string_b # yields False

Now we check whether any item in a list contains an item for which P - in item is True. We loop over a list with list comprehension:

lst = ['P - tag1', 'A - tag2', 'P - tag2', ' B - tag1', 'P - tag3']
any(['P -' in item for item in lst]) # Yields True because there are items containing 'P -'

Next we apply this to all our nested lists and count the number of items in your list using sum()

sum(any(['P -' in item for item in lst]) for lst in a)

Upvotes: 1

blue note
blue note

Reputation: 29081

Define a helper function to count elements having P in a list

def countP(lst):
    return sum(1 for item in lst if 'P-' in item)

and then, assuming my_list is your initial list, and n your threshold

result= sum(1 for sublist in my_list if countP(sublist) > n)

Upvotes: 0

Nouman
Nouman

Reputation: 7303

I have made a code that works as expected. It loops the the list and then loops through the item in the sub-list. If p - is found in the item then it adds 1 in total and break that loop immediately (because one P - tag is required in list) and continue to the next sub-list.

a = [['P - tag1', 'A - tag2', 'P - tag2', ' B - tag1', 'P - tag3'],['A - tag2', 'B - tag1'],['P - tag2', 'B - tag1','P - tag 3']]
contains = 0
for aa in a:
    for aaa in aa:
        if "P -" in aaa:
            contains += 1
            break
print(contains)

Upvotes: 0

Related Questions