Поиск всех позиций персонажа в строке

1

Я пытаюсь найти все номера индексов символа в строке python, используя очень простой набор навыков. Например, если у меня есть строка "Яблоки совершенно потрясающие", и я хочу найти места, где "a" находится в строке. Мой идеальный выход:

0
7
14
19

Это все места в строке, в которой появляется "a" (я думаю)

Это код, который у меня есть до сих пор:

sentence = input("Input a string: ")
for ch in sentence:
    x = sentence.find('o')


print(x)

Здесь я ищу "o" вместо a. Мой мыслительный процесс заключается в том, что для каждого символа в строке функция find вернет позицию "o". Поскольку я не знаю, как долго будет вводиться строка ввода, я использовал цикл for. Я могу найти и распечатать первый экземпляр "o", но не всех. Что я должен делать? Заранее спасибо!

  • 0
    Вы должны перебирать символы, используя for index, ch in enumerate(sentence) ; тогда простой проверки равенства будет достаточно, чтобы определить, печатать index или нет.
  • 0
    docs.python.org/3/library/stdtypes.html#str.find
Теги:
for-loop

3 ответа

2

Использование enumerate является стандартным способом. Хотя, вы можете воспользоваться скоростью str.find для критически важных операций.

Код

def find_all(s, c):
    idx = s.find(c)
    while idx != -1:
        yield idx
        idx = s.find(c, idx + 1)

print(*find_all('Apples are totally awesome', 'o')) # 12 23

Я сделал вышеупомянутый возврат генератора для элегантности и для учета очень больших строк. Разумеется, это может быть приложено к list случае необходимости.

эталонный тест

Здесь приведен пример сравнения с решением, использующим enumerate и понимание списка. Оба решения имеют линейную временную сложность, но str.find значительно быстрее.

import timeit

def find_all_enumerate(s, c):
    return [i for i, x in enumerate(s) if c == 'a']

print(
    'find_all:',
    timeit.timeit("list(find_all('Apples are totally awesome', 'o'))",
                  setup="from __main__ import find_all")
)

print(
    'find_all_enumerate:',
    timeit.timeit("find_all_enumerate('Apples are totally awesome', 'o')",
                  setup="from __main__ import find_all_enumerate")
)

Выход

find_all: 1.1554179692960915
find_all_enumerate: 1.9171753468076869
  • 0
    Это отличное решение.
  • 0
    @ StefhenRauch Ну, вы указали в этом направлении в другом комментарии, так что вы заслуживаете некоторого уважения
Показать ещё 3 комментария
1

Это хорошее место для перечисления, оно позволяет нам получить index and item когда мы зацикливаем, поэтому, если мы сопоставим item у нас может быть соответствующий index, также его полезно использовать .lower() чтобы избежать проблем с совпадающими случаями

s = 'Apples are totally awesome'

l = [idx for idx, item in enumerate(s.lower()) if 'o' in item]

Расширенный цикл:

l = []
for idx, item in enumerate(s.lower()):
    if 'o' in item:
        l.append(idx)
/python/stack$ python3.7 sum.py 
[12, 23]
  • 0
    Вы действительно должны рассмотреть возможность поиска .
  • 1
    @StephenRauch найти только находит первый случай
Показать ещё 3 комментария
1

Используйте для вас отличное представление:

[ind for ind, ch in enumerate(sentence) if ch.lower() == 'a']

вернет список всех номеров, которые вы хотите. Распечатайте по желанию.

И я предположил, что, основываясь на вашем примере, вас не волнует случай, следовательно, вызов функции lower(). Используя Python 3 asterisk splat operator (*), вы можете сделать все это как один лайнер; но что я оставлю в качестве упражнения для читателя.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню