2015-09-09 3 views
1

Искал это, но все ответы были за пределами моего объема, так как я все еще участвую. Я пытаюсь найти количество вхождений слова в строку. Я придумал следующий код, но получаю странные ответы.Поиск слов в строке

s = 'bobzbobz' 


word = 'bob' 



index = 0 
instance = [] 
while index < len(s): 
    instance.append(s.find(word,index)) 
    index += 1 
print len(instance) #instance = [0, 4, 4, 4, 4, -1, -1, -1]???? Why?? 

Это должно печатать 2, но я получаю 8. И причина в том, что я получаю много повторяющихся значений в моем списке экземпляров.

+0

Если это все, что вам нужно, 's.count (word)' сделает это за вас :-) – alexis

+1

Вы получаете -1, потому что, когда подстрока не найдена, find возвращает -1, вы продолжаете получать 4, потому что вы держите поиск последнего боба по мере того, как вы только перемещаете индекс на одно место –

+1

Чтобы узнать, что происходит с вашим кодом, подумайте, что произойдет, когда 'index' равен 1 ... – alexis

ответ

-1
s = 'bobzbobz' 
word = 'bob' 
print s.count(word) 
0

Есть гораздо более эффективные способы, но в вашем коде, вам нужно, чтобы проверить, когда находка возвращается -1 для не спички и увеличения индекса тем, что найти возвращается, когда вы получаете спичку, вы всегда добавляя независимо и только перемещение одного индекса, так что если есть позже матч вы продолжаете находить тот же начальный индекс подстроки:

s = 'bobobzbobz' 
word = 'bob' 

index = 0 
instance = [] 
while index < len(s) - len(word): 
    f = s.find(word, index) 
    if f != -1: 
     instance.append(f) 
     index = f 
    index += 1 
print (instance) 
[0, 2, 6] 

вы не можете использовать .count, когда вы хотите, чтобы рассмотреть перекрывающиеся подстроки, как в приведенном выше примере.

Чтобы разбить его на одну итерации с использованием s = 'bobzbobz':

s.find(word, 0) -> 0 # s[index:] -> 'bobzbobz' 
s.find(word, 1) -> 4 # s[index:] -> 'obzbobz' 
s.find(word, 2) -> 4 # s[index:] -> 'bzbobz' 
s.find(word, 3) -> 4 # s[index:] -> 'zbobz' 
s.find(word, 4) -> 4 # s[index:] -> 'bobz' 
s.find(word, 5) -> -1 # s[index:] -> 'obz' 
s.find(word, 6) -> -1 # s[index:] -> 'bz' 
s.find(word, 7) -> -1 # s[index:] -> 'z' 

Вы получаете четыре 4-е в списке вывода, как от индекса 1 к индексу 4 находки найти подстроку слово, начиная с индексом 4, после чего индекса переместился мимо последнего bob, т. е. индекса 4, так что вы получаете -1 добавленный каждый раз, когда find не находит совпадения.

0

Каждый звонок до find сканирует остальную часть строки, ища появления, начинающиеся дальше. Таким образом, вы продолжаете сопоставлять одно и то же событие bob, пока вы не пройдете мимо него. Чтобы проверить каждую позицию ровно один раз, используйте другой метод. Одним из возможных вариантов просто использует startswith():

n = 0 
for i in range(len(s)): 
    if s[i:].startswith("bob"): 
     n += 1 

Или что то же самое:

n = 0 
for i in range(len(s)): 
    if s.startswith("bob", i): 
     n += 1 

Есть все виды альтернатив с использованием цикла, но я думаю, что это красиво и понятно.

Смежные вопросы