¿Cómo puedo contar la cantidad de veces que una subcadena determinada está presente dentro de una cadena en Python?
Por ejemplo:
>>> 'foo bar foo'.numberOfOccurrences('foo')
2
¿Cómo puedo contar la cantidad de veces que una subcadena determinada está presente dentro de una cadena en Python?
Por ejemplo:
>>> 'foo bar foo'.numberOfOccurrences('foo')
2
Respuestas:
string.count(substring)
, como en:
>>> "abcdabcva".count("ab")
2
Como se señaló en los comentarios, esta es la forma de hacerlo para casos no superpuestos . Si necesita contar las ocurrencias superpuestas, será mejor que verifique las respuestas en: "¿ Python regex encuentra todas las coincidencias superpuestas? ", O simplemente verifique mi otra respuesta a continuación.
"GCAAAAAG".count("AAA")
que da 1, mientras que la respuesta correcta es 3?
count
obviamente es para coincidencias no superpuestas, que a menudo es lo que uno quiere hacer. stackoverflow.com/questions/5616822/… trata con coincidencias superpuestas, pero una expresión simple, aunque costosa, es:sum("GCAAAAAGH"[i:].startswith("AAA") for i in range(len("GCAAAAAGH")))
string.count(substring1) + string.count(substring2)
. Pero tenga en cuenta que este no es un método eficiente si hay muchas subcadenas porque contar cada subcadena requiere una iteración sobre la cadena principal.
''.join([substring1, substring2]).count(pattern)
es más eficiente que la solución sugerida anteriormente. Lo comprobé usando 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
Dependiendo de lo que realmente quiere decir, propongo las siguientes soluciones:
Te refieres a una lista de subcadenas separadas por espacios y quieres saber cuál es el número de posición de la subcadena entre todas las subcadenas:
s = 'sub1 sub2 sub3'
s.split().index('sub2')
>>> 1
Te refieres a la posición char de la subcadena en la cadena:
s.find('sub2')
>>> 5
Te refieres a los recuentos (no superpuestos) de apariencia de una su-bstring:
s.count('sub2')
>>> 1
s.count('sub')
>>> 3
s.find("su")
y te preguntas por qué lo haces 0
. Bueno, este es el primer índice de la subcadena "su"
en s
. Pruebe "ub"
y obtendrá 1
, intente, por ejemplo, "z"
y obtendrá -1
como en ninguna subcadena encontrada.
La mejor manera de encontrar subcadenas superpuestas en una cadena dada es usar la expresión regular de python, encontrará todas las coincidencias superpuestas usando la biblioteca de expresiones regulares. Aquí es cómo hacerlo a la izquierda es la subcadena y en la derecha proporcionará la cadena para que coincida
print len(re.findall('(?=aa)','caaaab'))
3
Para encontrar ocurrencias superpuestas de una subcadena en una cadena en Python 3, este algoritmo hará:
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
Yo mismo revisé este algoritmo y funcionó.
Puede contar la frecuencia de dos maneras:
Usando el count()
en str
:
a.count(b)
O puedes usar:
len(a.split(b))-1
¿Dónde a
está la cadena y b
la subcadena cuya frecuencia se va a calcular?
La mejor respuesta actual que involucra el método count
realmente no cuenta para las ocurrencias superpuestas y tampoco le importan las subcadenas vacías. Por ejemplo:
>>> a = 'caatatab'
>>> b = 'ata'
>>> print(a.count(b)) #overlapping
1
>>>print(a.count('')) #empty string
9
La primera respuesta debería ser 2
no1
, si tenemos en cuenta las subcadenas que se solapan. En cuanto a la segunda respuesta, es mejor si una subcadena vacía devuelve 0 como respuesta.
El siguiente código se ocupa de estas cosas.
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
Ahora cuando lo ejecutamos:
>>>num_of_patterns('caatatab', 'ata') #overlapping
2
>>>num_of_patterns('caatatab', '') #empty string
0
>>>num_of_patterns('abcdabcva','ab') #normal
2
Escenario 1: aparición de una palabra en una oración. por ejemplo: str1 = "This is an example and is easy"
. La aparición de la palabra "es". dejastr2 = "is"
count = str1.count(str2)
Escenario 2: aparición de un patrón en una oración.
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
¡Gracias!
La pregunta no es muy clara, pero responderé lo que eres, en la superficie, preguntando.
Una cadena S, que tiene una longitud de L caracteres y donde S [1] es el primer carácter de la cadena y S [L] es el último carácter, tiene las siguientes subcadenas:
Entonces, hay 0.5 * L * (L + 1) + 1 subcadenas dentro de una cadena de longitud L. Renderice esa expresión en Python, y tiene el número de subcadenas presentes dentro de la cadena.
Una forma es usar re.subn
. Por ejemplo, para contar el número de ocurrencias de 'hello'
cualquier combinación de casos que puede hacer:
import re
_, count = re.subn(r'hello', '', astring, flags=re.I)
print('Found', count, 'occurrences of "hello"')
Mantendré mi respuesta aceptada como la "forma simple y obvia de hacerlo"; sin embargo, eso no cubre las superposiciones. Averiguarlos se puede hacer ingenuamente, con múltiples comprobaciones de los cortes, como en: sum ("GCAAAAAGH" [i:]. Comienza con ("AAA") para i en rango (len ("GCAAAAAGH")))
(que produce 3): ¿se puede hacer mediante el uso engañoso de expresiones regulares, como se puede ver en Python regex encontrar todas las coincidencias superpuestas? - y también puede hacer golf de código fino - Este es mi recuento "hecho a mano" para la superposición de ocurrencias de patrones en una cadena que intenta no ser extremadamente ingenua (al menos no crea nuevos objetos de cadena en cada interacción):
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))
Ocurrencias superpuestas:
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')
Resultados:
my maaather lies over the oceaaan
6
4
2
Para el recuento superpuesto podemos usar use:
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
Para casos no superpuestos podemos usar la función count ():
string.count(sub_string)
¿Qué tal un one-liner con una lista de comprensión? Técnicamente sus 93 caracteres de largo, me ahorran el purismo PEP-8. La respuesta regex.findall es la más legible si se trata de un código de alto nivel. Si está creando algo de bajo nivel y no quiere dependencias, este es bastante delgado y malo. Estoy dando la respuesta superpuesta. Obviamente, use el conteo como la respuesta de mayor puntaje si no hay superposición.
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 desea contar todas las subcadenas (incluidas las superpuestas), utilice este método.
import re
def count_substring(string, sub_string):
regex = '(?='+sub_string+')'
# print(regex)
return len(re.findall(regex,string))
Si desea averiguar el recuento de subcadenas dentro de cualquier cadena; por favor use el siguiente código. El código es fácil de entender, por eso me salté los comentarios. :)
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
No estoy seguro de si esto ya es algo visto, pero pensé en esto como una solución para una palabra que es 'desechable':
for i in xrange(len(word)):
if word[:len(term)] == term:
count += 1
word = word[1:]
print count
Donde palabra es la palabra que está buscando y término es el término que está buscando
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)
Esto encuentra el número de veces que la subcadena se encuentra en la cadena y muestra el índice.
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)
Arriesgar un voto negativo porque más de 2 personas ya han proporcionado esta solución. Incluso voté a uno de ellos. Pero el mío es probablemente el más fácil de entender para los novatos.
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
Para una cadena simple con delimitación de espacio, usar Dict sería bastante rápido, consulte el código a continuación
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')
Podrías usar el startswith
método:
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 lógica a continuación funcionará para todas las cadenas y caracteres especiales
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"))
Aquí está la solución en Python 3 y no distingue entre mayúsculas y minúsculas:
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))
Esto hace una lista de todas las ocurrencias (también superpuestas) en la cadena y las cuenta
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])
Ejemplo:
str1 ='abcabcd'
str2 = 'bc'
creará esta lista pero solo guardará los valores BOLD :
[ab, bc , ca, ab, bc , cd]
eso devolverá:
len([bc, bc])
Aquí hay una solución que funciona tanto para casos no superpuestos como superpuestos. Para aclarar: una subcadena superpuesta es aquella cuyo último carácter es idéntico a su primer carácter.
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