Python'daki bir dize içinde belirli bir alt dizenin kaç kez bulunduğunu nasıl sayabilirim?
Örneğin:
>>> 'foo bar foo'.numberOfOccurrences('foo')
2
Python'daki bir dize içinde belirli bir alt dizenin kaç kez bulunduğunu nasıl sayabilirim?
Örneğin:
>>> 'foo bar foo'.numberOfOccurrences('foo')
2
Yanıtlar:
string.count(substring)
, gibi:
>>> "abcdabcva".count("ab")
2
Yorumlarda belirtildiği gibi, örtüşmeyen olaylar için bunu yapmanın yolu budur . Çakışan olayları saymanız gerekiyorsa, şu yanıtları kontrol etseniz iyi olur: " Python regex çakışan tüm eşleşmeleri buluyor mu? " Veya aşağıdaki diğer cevabımı kontrol et.
"GCAAAAAG".count("AAA")
1 verir, doğru cevap 3'tür?
count
açıkça üst üste gelmeyen maçlar içindir - ki çoğu zaman bir şey yapmak ister. stackoverflow.com/questions/5616822/… Çakışan eşleşmelerle ilgileniyor - ancak sum("GCAAAAAGH"[i:].startswith("AAA") for i in range(len("GCAAAAAGH")))
string.count(substring1) + string.count(substring2)
. Ancak, çok sayıda alt dize varsa bunun etkili bir yöntem olmadığını unutmayın, çünkü her bir alt dizeyi saymak ana dize üzerinde bir yineleme gerektirir.
''.join([substring1, substring2]).count(pattern)
yukarıda önerilen çözümden daha verimlidir. Timeit kullanarak kontrol ettim.
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
Gerçekten ne demek istediğinize bağlı olarak, aşağıdaki çözümleri öneriyorum:
Boşluklarla ayrılmış alt dizelerin bir listesini kastediyorsunuz ve tüm alt dizeler arasındaki alt dizgi konum numarasının ne olduğunu bilmek istiyorsunuz:
s = 'sub1 sub2 sub3'
s.split().index('sub2')
>>> 1
Dizedeki alt dizenin karakter konumunu kastediyorsunuz:
s.find('sub2')
>>> 5
Bir su-bstring'in (örtüşmeyen) görünüm sayılarını kastediyorsunuz:
s.count('sub2')
>>> 1
s.count('sub')
>>> 3
s.find("su")
ve neden aldığını merak ediyorsun 0
? Eh bu alt dizenin ilk endeksidir "su"
içinde s
. Deneyin "ub"
ve alacaksınız 1
, örneğin deneyin "z"
ve -1
hiçbir alt dize bulunamadı gibi alacaksınız .
Belirli bir dizede üst üste binen alt dizeyi bulmanın en iyi yolu, normal ifade kitaplığını kullanarak üst üste binen tüm eşleşmeyi bulacağı python düzenli ifadesini kullanmaktır. İşte bunu nasıl yapacağınız alt dize ve sağda dizeyi eşleştirmek için
print len(re.findall('(?=aa)','caaaab'))
3
Python 3'te bir dizede bir alt dizenin çakışan oluşumlarını bulmak için, bu algoritma şunları yapar:
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
Bu algoritmayı kendim kontrol ettim ve işe yaradı.
Frekansı iki yolla sayabilirsiniz:
Kullanılması count()
in str
:
a.count(b)
Veya şunları kullanabilirsiniz:
len(a.split(b))-1
a
Dize ve b
frekansı hesaplanacak alt dize nerede .
Mevcut en iyi yanıt yöntemi count
, örtüşen olayları saymaz ve boş alt dizeleri de umursamaz. Örneğin:
>>> a = 'caatatab'
>>> b = 'ata'
>>> print(a.count(b)) #overlapping
1
>>>print(a.count('')) #empty string
9
İlk cevap olmalıdır 2
değil 1
biz örtüşen alt dizeleri göz önüne alırsak,. İkinci cevaba gelince, boş bir alt dizginin asnwer olarak 0 döndürmesi daha iyidir.
Aşağıdaki kod bu şeylerle ilgilenir.
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
Şimdi çalıştırdığımızda:
>>>num_of_patterns('caatatab', 'ata') #overlapping
2
>>>num_of_patterns('caatatab', '') #empty string
0
>>>num_of_patterns('abcdabcva','ab') #normal
2
Senaryo 1: Bir cümlede bir kelimenin oluşması. örneğin: str1 = "This is an example and is easy"
. "İs" kelimesinin oluşumu. Haydistr2 = "is"
count = str1.count(str2)
Senaryo 2: Cümlenin içinde kalıp oluşumu.
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
Teşekkürler!
Soru çok net değil, ama yüzeyde ne olduğunu sordum.
L karakter uzunluğunda ve S [1] dizenin ilk karakteri ve S [L] son karakter olduğunda S dizesi aşağıdaki alt dizelere sahiptir:
Bu nedenle, L uzunluğunda bir dizede 0,5 * L * (L + 1) + 1 alt dizesi vardır.
Bunun bir yolu kullanmaktır re.subn
. Örneğin, 'hello'
herhangi bir vaka karışımındaki olay sayısını saymak için şunları yapabilirsiniz:
import re
_, count = re.subn(r'hello', '', astring, flags=re.I)
print('Found', count, 'occurrences of "hello"')
Kabul edilen cevabımı "bunu yapmanın basit ve açık bir yolu" olarak tutacağım - ancak bu örtüşen olayları kapsamaz. Bunları bulmak dilimler çoklu kontrol ile saf olarak yapılabilir - olduğu gibi: sum ("GCAAAAAGH" [i:]. Aralıktaki i için (len ("GCAAAAAGH")) başlar ("AAA")
(Bu 3 verir) - Python regex tüm örtüşen maçlar bulmak gibi düzenli ifadeler hile kullanımı ile yapılabilir ? - ve aynı zamanda ince kod golf yapmak için yapabilir - Bu benim "el yapımı" sayım son derece naif değil çalışır bir dizede üst üste gelen desen için (en azından her etkileşim yeni dize nesneleri oluşturmaz):
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))
Çakışan olaylar:
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')
Sonuçlar:
my maaather lies over the oceaaan
6
4
2
Çakışan sayım için kullanımı kullanabiliriz:
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
Çakışan olmayan durumlarda count () işlevini kullanabiliriz:
string.count(sub_string)
Liste kavrayışı olan bir astardan ne haber? Teknik olarak 93 karakter uzunluğunda, bana PEP-8 saflığını koruyor. Regex.findall cevabı, yüksek düzeyde bir kod parçası ise en okunabilir cevaptır. Düşük bir şey inşa ediyorsanız ve bağımlılıklar istemiyorsanız, bu oldukça yalın ve anlamlıdır. Çakışan cevabı veriyorum. Açıkçası, çakışma yoksa sayıyı en yüksek puan yanıtı gibi kullanı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])
Tüm alt dizeyi (üst üste binenler dahil) saymak istiyorsanız, bu yöntemi kullanın.
import re
def count_substring(string, sub_string):
regex = '(?='+sub_string+')'
# print(regex)
return len(re.findall(regex,string))
Herhangi bir dizenin içindeki alt dize sayısını öğrenmek istiyorsanız; lütfen aşağıdaki kodu kullanın. Kodu anlamak kolay bu yüzden yorumları atladı. :)
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
Bunun bir şeye bakıp bakmadığından emin değilim, ama bunu 'tek kullanımlık' bir kelimeye çözüm olarak düşündüm:
for i in xrange(len(word)):
if word[:len(term)] == term:
count += 1
word = word[1:]
print count
Nerede kelime kelime içeri arıyorsunuz ve terim Aradığınız terimdir
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)
Bu, dizede alt dizenin kaç kez bulunduğunu bulur ve dizini görüntüler.
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)
2'den fazla kişi bu çözümü zaten sağladığından bir aşağı oyu tehlikeye atmak Hatta onlardan birini bile iptal ettim. Ama benimki yeni başlayanlar için muhtemelen en kolay olanıdır.
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
Alan sınırlamalı basit bir dize için Dict kullanmak oldukça hızlı olur, lütfen aşağıdaki koda bakı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')
startswith
Yöntemi kullanabilirsiniz :
def count_substring(string, sub_string):
x = 0
for i in range(len(string)):
if string[i:].startswith(sub_string):
x += 1
return x
Aşağıdaki mantık tüm dize ve özel karakterler için çalışacaktır
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"))
İşte Python 3'teki çözüm ve büyük / küçük harf duyarsız:
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)
#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))
Bu, dizedeki tüm oluşumların (ayrıca çakışan) bir listesini yapar ve bunları sayar
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])
Misal:
str1 ='abcabcd'
str2 = 'bc'
bu listeyi oluşturur, ancak yalnızca BOLD değerlerini kaydeder :
[ab, bc , ca, ab, bc , cd]
geri dönecek:
len([bc, bc])
Üst üste binmeyen ve çakışan olaylar için çalışan bir çözüm. Açıklığa kavuşturmak için: örtüşen bir alt dize, son karakteri ilk karakterine özdeş olan alt dizedir.
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