Comment puis-je compter le nombre de fois qu'une sous-chaîne donnée est présente dans une chaîne en Python?
Par exemple:
>>> 'foo bar foo'.numberOfOccurrences('foo')
2
Comment puis-je compter le nombre de fois qu'une sous-chaîne donnée est présente dans une chaîne en Python?
Par exemple:
>>> 'foo bar foo'.numberOfOccurrences('foo')
2
Réponses:
string.count(substring), comme dans:
>>> "abcdabcva".count("ab")
2
Comme indiqué dans les commentaires, c'est la façon de procéder pour les occurrences qui ne se chevauchent pas . Si vous avez besoin de compter les occurrences qui se chevauchent, vous feriez mieux de vérifier les réponses à: " Python regex trouver toutes les correspondances qui se chevauchent? ", Ou tout simplement vérifier mon autre réponse ci-dessous.
"GCAAAAAG".count("AAA")qui donne 1, tandis que la bonne réponse est 3?
countest évidemment pour les correspondances qui ne se chevauchent pas - ce qui est le plus souvent ce que l'on veut faire. stackoverflow.com/questions/5616822/… traite des correspondances qui se chevauchent - mais une expression simple, mais coûteuse, est:sum("GCAAAAAGH"[i:].startswith("AAA") for i in range(len("GCAAAAAGH")))
string.count(substring1) + string.count(substring2). Mais gardez à l'esprit que ce n'est pas une méthode efficace s'il y a beaucoup de sous-chaînes car le comptage de chaque sous-chaîne nécessite une itération sur la chaîne principale.
''.join([substring1, substring2]).count(pattern)est plus efficace que la solution suggérée ci-dessus. J'ai vérifié en utilisant timeit.
s = 'arunununghhjj'
sb = 'nun'
results = 0
sub_len = len(sb)
for i in range(len(s)):
if s[i:i+sub_len] == sb:
results += 1
print results
Selon ce que vous voulez vraiment dire, je vous propose les solutions suivantes:
Vous voulez dire une liste de sous-chaînes séparées par des espaces et vous voulez savoir quel est le numéro de position de la sous-chaîne parmi toutes les sous-chaînes:
s = 'sub1 sub2 sub3'
s.split().index('sub2')
>>> 1Vous voulez dire la position char de la sous-chaîne dans la chaîne:
s.find('sub2')
>>> 5Vous voulez dire que les (non-chevauchement) compte d'apparition d'un su-bstring:
s.count('sub2')
>>> 1
s.count('sub')
>>> 3s.find("su")et vous demandez pourquoi vous obtenez 0? Eh bien , c'est le premier indice de la sous-chaîne "su"dans s. Essayez "ub"et vous obtiendrez 1, essayez par exemple "z"et vous obtiendrez -1comme dans aucune sous-chaîne trouvée.
La meilleure façon de trouver une sous-chaîne qui se chevauchent dans une chaîne donnée est d'utiliser l'expression régulière python, elle trouvera toutes les correspondances qui se chevauchent en utilisant la bibliothèque d'expressions régulières. Voici comment le faire à gauche est la sous-chaîne et à droite vous fournirez la chaîne à faire correspondre
print len(re.findall('(?=aa)','caaaab'))
3
Pour trouver les occurrences qui se chevauchent d'une sous-chaîne dans une chaîne en Python 3, cet algorithme fera:
def count_substring(string,sub_string):
l=len(sub_string)
count=0
for i in range(len(string)-len(sub_string)+1):
if(string[i:i+len(sub_string)] == sub_string ):
count+=1
return count
J'ai moi-même vérifié cet algorithme et cela a fonctionné.
Vous pouvez compter la fréquence de deux manières:
Utilisation de count()in str:
a.count(b)
Ou, vous pouvez utiliser:
len(a.split(b))-1
Où aest la chaîne et bla sous-chaîne dont la fréquence doit être calculée.
La meilleure méthode de réponse actuelle countne compte pas vraiment pour les occurrences qui se chevauchent et ne se soucie pas non plus des sous-chaînes vides. Par exemple:
>>> a = 'caatatab'
>>> b = 'ata'
>>> print(a.count(b)) #overlapping
1
>>>print(a.count('')) #empty string
9
La première réponse ne devrait 2pas être 1, si l'on considère les sous-chaînes qui se chevauchent. Quant à la deuxième réponse, il est préférable qu'une sous-chaîne vide renvoie 0 comme réponse.
Le code suivant s'occupe de ces choses.
def num_of_patterns(astr,pattern):
astr, pattern = astr.strip(), pattern.strip()
if pattern == '': return 0
ind, count, start_flag = 0,0,0
while True:
try:
if start_flag == 0:
ind = astr.index(pattern)
start_flag = 1
else:
ind += 1 + astr[ind+1:].index(pattern)
count += 1
except:
break
return count
Maintenant, quand nous l'exécutons:
>>>num_of_patterns('caatatab', 'ata') #overlapping
2
>>>num_of_patterns('caatatab', '') #empty string
0
>>>num_of_patterns('abcdabcva','ab') #normal
2
Scénario 1: occurrence d'un mot dans une phrase. par exemple: str1 = "This is an example and is easy". L'occurrence du mot "est". laissestr2 = "is"
count = str1.count(str2)
Scénario 2: occurrence du motif dans une phrase.
string = "ABCDCDC"
substring = "CDC"
def count_substring(string,sub_string):
len1 = len(string)
len2 = len(sub_string)
j =0
counter = 0
while(j < len1):
if(string[j] == sub_string[0]):
if(string[j:j+len2] == sub_string):
counter += 1
j += 1
return counter
Merci!
La question n'est pas très claire, mais je vais répondre à ce que vous demandez, à première vue.
Une chaîne S, longue de L caractères, et où S [1] est le premier caractère de la chaîne et S [L] est le dernier caractère, a les sous-chaînes suivantes:
Donc, il y a 0,5 * L * (L + 1) + 1 sous-chaînes dans une chaîne de longueur L. Rendez cette expression en Python, et vous avez le nombre de sous-chaînes présentes dans la chaîne.
Une façon est d'utiliser re.subn. Par exemple, pour compter le nombre d'occurrences de 'hello'dans n'importe quelle combinaison de cas, vous pouvez faire:
import re
_, count = re.subn(r'hello', '', astring, flags=re.I)
print('Found', count, 'occurrences of "hello"')
Je garderai ma réponse acceptée comme étant "la manière simple et évidente de le faire" - mais cela ne couvre pas les événements qui se chevauchent. Les découvrir peut être fait naïvement, avec plusieurs vérifications des tranches - comme dans: sum ("GCAAAAAGH" [i:]. Commence par ("AAA") pour i dans la plage (len ("GCAAAAAGH")))
(ce qui donne 3) - cela peut être fait en utilisant des expressions régulières, comme on peut le voir sur regex Python trouver toutes les correspondances qui se chevauchent? - et cela peut aussi faire du golf à code fin - C'est mon compte "fait à la main" pour les superpositions de motifs dans une chaîne qui essaie de ne pas être extrêmement naïf (au moins, il ne crée pas de nouveaux objets de chaîne à chaque interaction):
def find_matches_overlapping(text, pattern):
lpat = len(pattern) - 1
matches = []
text = array("u", text)
pattern = array("u", pattern)
indexes = {}
for i in range(len(text) - lpat):
if text[i] == pattern[0]:
indexes[i] = -1
for index, counter in list(indexes.items()):
counter += 1
if text[i] == pattern[counter]:
if counter == lpat:
matches.append(index)
del indexes[index]
else:
indexes[index] = counter
else:
del indexes[index]
return matches
def count_matches(text, pattern):
return len(find_matches_overlapping(text, pattern))
Occurrences qui se chevauchent:
def olpcount(string,pattern,case_sensitive=True):
if case_sensitive != True:
string = string.lower()
pattern = pattern.lower()
l = len(pattern)
ct = 0
for c in range(0,len(string)):
if string[c:c+l] == pattern:
ct += 1
return ct
test = 'my maaather lies over the oceaaan'
print test
print olpcount(test,'a')
print olpcount(test,'aa')
print olpcount(test,'aaa')
Résultats:
my maaather lies over the oceaaan
6
4
2
Pour le nombre de chevauchements, nous pouvons utiliser:
def count_substring(string, sub_string):
count=0
beg=0
while(string.find(sub_string,beg)!=-1) :
count=count+1
beg=string.find(sub_string,beg)
beg=beg+1
return count
Pour les cas sans chevauchement, nous pouvons utiliser la fonction count ():
string.count(sub_string)
Que diriez-vous d'un one-liner avec une compréhension de la liste? Techniquement ses 93 caractères de long, m'épargnent le purisme du PEP-8. La réponse regex.findall est la plus lisible si c'est un morceau de code de haut niveau. Si vous construisez quelque chose de bas niveau et ne voulez pas de dépendances, celui-ci est plutôt maigre et méchant. Je donne la réponse qui se chevauchent. Évidemment, utilisez simplement count comme la réponse la plus élevée s'il n'y a pas de chevauchement.
def count_substring(string, sub_string):
return len([i for i in range(len(string)) if string[i:i+len(sub_string)] == sub_string])
Si vous souhaitez compter toute la sous-chaîne (y compris les chevauchements), utilisez cette méthode.
import re
def count_substring(string, sub_string):
regex = '(?='+sub_string+')'
# print(regex)
return len(re.findall(regex,string))
Si vous souhaitez connaître le nombre de sous-chaînes dans une chaîne; veuillez utiliser le code ci-dessous. Le code est facile à comprendre, c'est pourquoi j'ai sauté les commentaires. :)
string=raw_input()
sub_string=raw_input()
start=0
answer=0
length=len(string)
index=string.find(sub_string,start,length)
while index<>-1:
start=index+1
answer=answer+1
index=string.find(sub_string,start,length)
print answer
Je ne sais pas si c'est déjà quelque chose à regarder, mais j'ai pensé à cela comme une solution pour un mot qui est «jetable»:
for i in xrange(len(word)):
if word[:len(term)] == term:
count += 1
word = word[1:]
print count
Où mot est le mot que vous recherchez et terme est le terme que vous recherchez
string="abc"
mainstr="ncnabckjdjkabcxcxccccxcxcabc"
count=0
for i in range(0,len(mainstr)):
k=0
while(k<len(string)):
if(string[k]==mainstr[i+k]):
k+=1
else:
break
if(k==len(string)):
count+=1;
print(count)
import re
d = [m.start() for m in re.finditer(seaching, string)]
print (d)
Cela trouve le nombre de fois que la sous-chaîne a été trouvée dans la chaîne et affiche l'index.
my_string = """Strings are amongst the most popular data types in Python.
We can create the strings by enclosing characters in quotes.
Python treats single quotes the same as double quotes."""
Count = my_string.lower().strip("\n").split(" ").count("string")
Count = my_string.lower().strip("\n").split(" ").count("strings")
print("The number of occurance of word String is : " , Count)
print("The number of occurance of word Strings is : " , Count)
Risquer un downvote car 2+ autres ont déjà fourni cette solution. J'ai même voté pour l'un d'entre eux. Mais le mien est probablement le plus facile à comprendre pour les débutants.
def count_substring(string, sub_string):
slen = len(string)
sslen = len(sub_string)
range_s = slen - sslen + 1
count = 0
for i in range(range_s):
if (string[i:i+sslen] == sub_string):
count += 1
return count
Pour une chaîne simple avec délimitation d'espace, l'utilisation de Dict serait assez rapide, veuillez consulter le code ci-dessous
def getStringCount(mnstr:str, sbstr:str='')->int:
""" Assumes two inputs string giving the string and
substring to look for number of occurances
Returns the number of occurances of a given string
"""
x = dict()
x[sbstr] = 0
sbstr = sbstr.strip()
for st in mnstr.split(' '):
if st not in [sbstr]:
continue
try:
x[st]+=1
except KeyError:
x[st] = 1
return x[sbstr]
s = 'foo bar foo test one two three foo bar'
getStringCount(s,'foo')
Vous pouvez utiliser la startswithméthode:
def count_substring(string, sub_string):
x = 0
for i in range(len(string)):
if string[i:].startswith(sub_string):
x += 1
return x
La logique ci-dessous fonctionnera pour toutes les chaînes et caractères spéciaux
def cnt_substr(inp_str, sub_str):
inp_join_str = ''.join(inp_str.split())
sub_join_str = ''.join(sub_str.split())
return inp_join_str.count(sub_join_str)
print(cnt_substr("the sky is $blue and not greenthe sky is $blue and not green", "the sky"))
Voici la solution en Python 3 et insensible à la casse:
s = 'foo bar foo'.upper()
sb = 'foo'.upper()
results = 0
sub_len = len(sb)
for i in range(len(s)):
if s[i:i+sub_len] == sb:
results += 1
print(results)
j = 0
while i < len(string):
sub_string_out = string[i:len(sub_string)+j]
if sub_string == sub_string_out:
count += 1
i += 1
j += 1
return count
#counting occurence of a substring in another string (overlapping/non overlapping)
s = input('enter the main string: ')# e.g. 'bobazcbobobegbobobgbobobhaklpbobawanbobobobob'
p=input('enter the substring: ')# e.g. 'bob'
counter=0
c=0
for i in range(len(s)-len(p)+1):
for j in range(len(p)):
if s[i+j]==p[j]:
if c<len(p):
c=c+1
if c==len(p):
counter+=1
c=0
break
continue
else:
break
print('number of occurences of the substring in the main string is: ',counter)
s = input('enter the main string: ')
p=input('enter the substring: ')
l=[]
for i in range(len(s)):
l.append(s[i:i+len(p)])
print(l.count(p))
Cela fait une liste de toutes les occurrences (qui se chevauchent également) dans la chaîne et les compte
def num_occ(str1, str2):
l1, l2 = len(str1), len(str2)
return len([str1[i:i + l2] for i in range(l1 - l2 + 1) if str1[i:i + l2] == str2])
Exemple:
str1 ='abcabcd'
str2 = 'bc'
créera cette liste mais n'enregistrera que les valeurs BOLD :
[ab, bc , ca, ab, bc , cd]
qui reviendra:
len([bc, bc])
Voici une solution qui fonctionne à la fois pour les occurrences qui ne se chevauchent pas et qui se chevauchent. Pour clarifier: une sous-chaîne qui se chevauche est une sous-chaîne dont le dernier caractère est identique à son premier caractère.
def substr_count(st, sub):
# If a non-overlapping substring then just
# use the standard string `count` method
# to count the substring occurences
if sub[0] != sub[-1]:
return st.count(sub)
# Otherwise, create a copy of the source string,
# and starting from the index of the first occurence
# of the substring, adjust the source string to start
# from subsequent occurences of the substring and keep
# keep count of these occurences
_st = st[::]
start = _st.index(sub)
cnt = 0
while start is not None:
cnt += 1
try:
_st = _st[start + len(sub) - 1:]
start = _st.index(sub)
except (ValueError, IndexError):
return cnt
return cnt