Reputation: 39
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
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
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
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
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
Reputation: 917
I have already seen some nice answers here, however, here is also an explanation of why these work.
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
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
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