Pythonでの重複を含む、特定の文字列の出現回数をカウントする最良の方法は何ですか?それは最も明白な方法ですか:
def function(string, str_to_search_for):
count = 0
for x in xrange(len(string) - len(str_to_search_for) + 1):
if string[x:x+len(str_to_search_for)] == str_to_search_for:
count += 1
return count
function('1011101111','11')
returns 5
?
またはPythonでより良い方法がありますか?
さて、これはmight Cでの比較を行うので高速です:
def occurrences(string, sub):
count = start = 0
while True:
start = string.find(sub, start) + 1
if start > 0:
count+=1
else:
return count
>>> import re
>>> text = '1011101111'
>>> len(re.findall('(?=11)', text))
5
マッチのリスト全体をメモリにロードしたくない場合、これは問題になりません!本当に望むならこれを行うことができます:
>>> sum(1 for _ in re.finditer('(?=11)', text))
5
関数として(re.escape
は、部分文字列が正規表現に干渉しないことを確認します)。
>>> def occurrences(text, sub):
return len(re.findall('(?={0})'.format(re.escape(sub)), text))
>>> occurrences(text, '11')
5
new Python regex module ]を使用して試すこともできます。これは重複する一致をサポートします。
import regex as re
def count_overlapping(text, search_for):
return len(re.findall(search_for, text, overlapped=True))
count_overlapping('1011101111','11') # 5
Pythonのstr.count
は、重複しない部分文字列をカウントします。
In [3]: "ababa".count("aba")
Out[3]: 1
重複するシーケンスをカウントする方法はいくつかありますが、もっとたくさんあると思います:)
In [10]: re.findall("a(?=ba)", "ababa")
Out[10]: ['a', 'a']
In [11]: data = "ababa"
In [17]: sum(1 for i in range(len(data)) if data.startswith("aba", i))
Out[17]: 2
s = "bobobob"
sub = "bob"
ln = len(sub)
print(sum(sub == s[i:i+ln] for i in xrange(len(s)-(ln-1))))
この関数(別のソリューション!)は、パターンとテキストを受け取ります。とその位置にあるすべての部分文字列を含むリストを返します。
def occurrences(pattern, text):
"""
input: search a pattern (regular expression) in a text
returns: a list of substrings and their positions
"""
p = re.compile('(?=({0}))'.format(pattern))
matches = re.finditer(p, text)
return [(match.group(1), match.start()) for match in matches]
print (occurrences('ana', 'banana'))
print (occurrences('.ana', 'Banana-fana fo-fana'))
[( 'ana'、1)、( 'ana'、3)]
[( 'Bana'、0)、( 'nana'、2)、( 'fana'、7)、( 'fana'、15)]
def count_substring(string, sub_string):
count = 0
for pos in range(len(string)):
if string[pos:].startswith(sub_string):
count += 1
return count
これが最も簡単な方法です。
コースのボブの質問に対する私の答え:
s = 'azcbobobegghaklbob'
total = 0
for i in range(len(s)-2):
if s[i:i+3] == 'bob':
total += 1
print 'number of times bob occurs is: ', total
ここではリストの内包表記を使用するのがかなりPython的な方法ですが、おそらく最も効率的ではありません。
sequence = 'abaaadcaaaa'
substr = 'aa'
counts = sum([
sequence.startswith(sub, i) for i in range(len(sequence))
])
print(counts) # 5
リストは[False, False, True, False, False, False, True, True, False, False]
になります。これは、文字列を介してすべてのインデックスをチェックするためです。int(True) == 1
であるため、sum
は一致の総数を示します。
def count_substring(string, sub_string):
counter = 0
for i in range(len(string)):
if string[i:].startswith(sub_string):
counter = counter + 1
return counter
上記のコードは、文字列全体を一度ループし、カウントされている特定の部分文字列で始まる文字列があるかどうかをチェックし続けます。
ここに私のedX MIT "find bob" *ソリューション(* sという名前の文字列内の "bob"オカレンスの数を検索)があります。
s = 'azcbobobegghakl'
count = 0
while 'bob' in s:
count += 1
s = s[(s.find('bob') + 2):]
print "Number of times bob occurs is: {}".format(count)
これは正規表現を使用して解決できます。
import re
def function(string, sub_string):
match = re.findall('(?='+sub_string+')',string)
return len(match)
文字列が大きい場合、要約では Rabin-Karp を使用します。
これはstr.find()
を使用する別の例ですが、答えが多いため、必要以上に複雑になっています。
def occurrences(text, sub):
c, n = 0, text.find(sub)
while n != -1:
c += 1
n = text.find(sub, n+1)
return c
In []:
occurrences('1011101111', '11')
Out[]:
5
部分文字列の出現をカウントする簡単な方法は、count()
を使用することです。
_>>> s = 'bobob'
>>> s.count('bob')
1
_
重複する部分がわかっている場合は、replace ()
を使用して重複する文字列を見つけることができます。
_>>> s = 'bobob'
>>> s.replace('b', 'bb').count('bob')
2
_
静的であることに加えて、他の制限があることに注意してください。
_>>> s = 'aaa'
>>> count('aa') # there must be two occurrences
1
>>> s.replace('a', 'aa').count('aa')
3
_
Given
sequence = '1011101111'
sub = "11"
コード
この特定の場合:
sum(x == Tuple(sub) for x in Zip(sequence, sequence[1:]))
# 5
より一般的には、これ
windows = Zip(*([sequence[i:] for i, _ in enumerate(sequence)][:len(sub)]))
sum(x == Tuple(sub) for x in windows)
# 5
またはジェネレーターに拡張:
import itertools as it
iter_ = (sequence[i:] for i, _ in enumerate(sequence))
windows = Zip(*(it.islice(iter_, None, len(sub))))
sum(x == Tuple(sub) for x in windows)
代替
import more_itertools as mit
len(list(mit.locate(sequence, pred=lambda *args: args == Tuple(sub), window_size=len(sub))))
# 5
入力として2つの文字列を取り、重複を含む文字列でsubが発生する回数をカウントする関数。 subが部分文字列かどうかを確認するために、in
演算子を使用しました。
def count_Occurrences(string, sub):
count=0
for i in range(0, len(string)-len(sub)+1):
if sub in string[i:i+len(sub)]:
count=count+1
print 'Number of times sub occurs in string (including overlaps): ', count
複製された question の場合、3で3カウントし、文字列を比較することにしました。
counted = 0
for i in range(len(string)):
if string[i*3:(i+1)*3] == 'xox':
counted = counted +1
print counted
def count_overlaps (string, look_for):
start = 0
matches = 0
while True:
start = string.find (look_for, start)
if start < 0:
break
start += 1
matches += 1
return matches
print count_overlaps ('abrabra', 'abra')
受け入れられた答えに非常に近い代替方法ですが、ループ内にwhile
を含める代わりにif
テストとしてif
を使用します。
def countSubstr(string, sub):
count = 0
while sub in string:
count += 1
string = string[string.find(sub) + 1:]
return count;
これにより、while True:
そして私の意見では少しきれいです