简体   繁体   中英

Try to find the number of times an item appears in another list of list of string

I have this list of list of str and another search list number :

animal = [[['cat', 'cat', 'dog'], ['cat', 'cat', 'dog'], ['cat', 'cat', 'dog']]
number = ['cat', 'dog']

how do I make it on python so that it calculates the number of times each str inside number can be found in animal? for example, for 'cat' the answer would be 6 and for dog it would be 3. I tried to use the count method for list, but it works only if I have a str, I need it to search it using the list.

I tried to do a for loop (only for the first index):

found = 0
for char in animal:
    if str(number[0]) in str(animal):
        found = found+1
return found

the problem is that I cannot do that if I have an infinite number of str in number! If I have let's say 10 str in number I would have to do that loop for [0],[1],[2],[3],[4],[5],... which can take a lot of time.

You may want to try this simple Counter :


from collections import Counter

L =  ['cat', 'cat', 'dog']
to_search = ['cat', 'dog']

counts = Counter(L)       # a dictionary - find item is O(1) 
print(counts)


for item in to_search:
    if item in counts:
        print(item, counts[item])

Output:

cat 2
dog 1

If you're only interested in search one single word/animal, you can just do this:

search_word  = 'cat'
print(counts[search_word])    # 2

You could use a dictionary:

animal = ['cat', 'cat', 'dog']
number = ['cat', 'dog']

counter_dict = dict()
for value in animal:
    #remove following 2 lines to count all unique values
    if value not in number: 
        continue #skip if not counting this value
    #get() function returns None if the key wasn't created yet
    #"or" part makes sure prev_count is number - None or 0 == 0
    prev_count = counter_dict.get(value) or 0
    counter_dict[value] = prev_count + 1
print(counter_dict)

Output: {'cat': 2, 'dog': 1}

Note: the "or" trick only works because I want 0 to be the default:
None or x returns x , but 0 or x also returns x . Since x is 0 in this specific case, it doesn't make a difference. It would be more proper to use

prev_count = counter_dict.get(value)
counter_dict[value] = 1 if prev_count is None else (prev_count + 1)

But that looks much less pretty

you could try this in simple form

list2 = ['cat', 'cat', 'dog']
number = ['cat', 'dog']


print([list2.count(j) for j in number])

output

[2, 1] #2 is times he find the first value 'cat' inside list2

using pandas library without loops

list2 = ['cat', 'cat', 'dog']
number = ['cat', 'dog']
flatten_list = [['cat', 'cat', 'dog'], ['cat', 'cat', 'dog'], ['cat', 'cat', 'dog']]

import pandas as pd



from itertools import chain
def get(arr):
    
   if type(arr[0])==list:
       # if you have 2d array then make it 1d ex [[2],[4]] => [2,4]
       arr = list(chain.from_iterable(arr))
    

       counts = pd.Series(arr).value_counts() # return how many times the value repeated inside your array
       print(counts)# print result without loop

       # another way using loop same result
       print([arr.count(j) for j in number])

get(flatten_list) 
get(list2) 

or with 2 for loop for 2d array

print([sum(i == item for a in flatten_list for i in a) for item in number]) 

output [6,3]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM