2013-09-23 2 views
0

Я полный новичок в Python, и я пытаюсь найти индексы для каждого «o» в этой строке. Это только показывает индекс для первого о, в то время как я пытаюсь найти все из них:Найти индексы для определенного символа в строке

besedilo = "Dober dan Slovenija" 
    print (besedilo.index("o")) 

Я думал, что я мог бы использовать цикл, но я не совсем уверен, как это сделать

ответ

2

Используйте список понимание с enumerate():

indices = [i for i, c in enumerate(besedilo) if c == 'o'] 

Демо:

>>> besedilo = "Dober dan Slovenija" 
>>> [i for i, c in enumerate(besedilo) if c == 'o'] 
[1, 12] 

str.index() method также принимает необязательный start аргумент, начальный индекс, с которого для поиска (по умолчанию 0), так вы может построить петлю с последним местоположением + 1, чтобы собрать все индексы:

indices = [] 
next = -1 
while True: 
    try: 
     next = besedilo.index(next + 1) 
     indices.append(next) 
    except ValueError: 
     break 

Если скорость является проблемой, то этот последний метод является на самом деле быстрее вариант из двух:

$ bin/python -m timeit -s "test = 'Dober dan Slovenija'" "indices = [i for i, c in enumerate(test) if c=='o']" 
100000 loops, best of 3: 2.51 usec per loop 
$ bin/python -m timeit -s "test = 'Dober dan Slovenija'" -s "indices,next=[],-1" "while True:" " try:" "  next= test.index('o', next+1)" "  indices.append(next)" " except ValueError: break" 
1000000 loops, best of 3: 1.06 usec per loop 
+0

Является ли понимание списка всегда быстрее или только для более коротких строк? Я бы ожидал, что индексный метод будет выигрывать для необычного символа в длинной строке. Также, конечно, цикл с использованием индекса работает намного лучше, чем ваше перечисляющее решение, если строка поиска длиннее одного символа. – Duncan

+0

@ Duncan: оба метода должны сканировать всю строку, а методы поиска 'str.index()' и 'list.append()' и вызовы также берут свои потери с более высокой постоянной стоимостью. У меня нет времени прямо сейчас, чтобы сделать правильное испытание 'timeit'; мой инстинкт кишки говорит мне, что список comp выиграет больше всего, если не во всех случаях. –

+0

Никогда не доверяйте своей кишке. 'python -m timeit -s 'test =' Dober dan Slovenija '" "indices = [i для i, c в перечислении (тест), если c ==' o ']" '100000 циклов, лучше всего 3: 3.6 usec за loop 'python -m timeit -s" test = 'Dober dan Slovenija' "-s" index, next = [], - 1 "" while True: "" try: "" next = test.index ('o', next + 1) "" indices.append (next) "" за исключением ValueError: break "' 1000000 циклов, лучше всего 3: 1.09 usec за цикл. Цикл while выигрывает каждую строку, которую я пробовал. Когда я попытался использовать строку «x» * 1000 + «o'', она выиграла в 182 раз. – Duncan

2

Использование enumerate() :

>>> besedilo = "Dober dan Slovenija" 
>>> [i for i, j in enumerate(besedilo) if j == 'o'] 
[1, 12] 

Это будет цикл через обе строки и своего рода счетчиком, начиная с 0. Если буква соответствует 'o', то счетчик будет в списке, возвращаемом в списке понимание.

В качестве альтернативы, вы можете использовать модуль itertools:

>>> import itertools 
>>> [i for i, j in itertools.izip(itertools.count(), besedilo) if j == 'o'] # itertools.izip not needed if you are using Python 3 
[1, 12] 

Имейте в виду, что enumerate() гораздо эффективнее :).

+0

'itertools.izip (itertools.count(), ...)' не является самым эффективным альтернатива простому перечислению() '.. –

+0

@MartijnPieters Конечно нет. Мне просто хотелось добавить его: p – TerryA

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