简体   繁体   中英

Finding All Positions Of A Character In A String

I'm trying to find all the index numbers of a character in a python string using a very basic skill set. For example if I have the string "Apples are totally awesome" and I want to find the places where 'a' is in the string. My ideal output would be:

0
7
14
19

These are all the places in the string that an 'a' appears (I think)

This is the code I have so far:

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


print(x)

Here I'm looking for 'o' instead of a. My thought process is that for each character in the string the find function will return the position of the 'o'. Since I don't know how long the input string will be necessarily I used a for loop. I'm able to find and print out the first instance of an 'o' but not all of them. What should I do? Thanks in advance!

Using enumerate is the standard way to go. Although, you can take advantage of the speed of str.find for time-critical operations.

Code

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

I made the above return a generator for elegance and to account for very large strings. Put it can of course be casted to a list if need be.

Benchmark

Here is a benchmark against a solution using enumerate and a list-comprehension. Both solutions have linear time-complexity, but str.find is significantly faster.

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")
)

Output

find_all: 1.1554179692960915
find_all_enumerate: 1.9171753468076869

This is a good spot for enumerate , it allows us to get the index and item when we loop, so if we match the item we can have the corresponding index , also its helpful to use .lower() to avoid issues with matching cases

s = 'Apples are totally awesome'

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

Extended loop:

l = []
for idx, item in enumerate(s.lower()):
    if 'o' in item:
        l.append(idx)
 /python/stack$ python3.7 sum.py [12, 23]

Use you a list comprehension for great good:

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

will return a list of all the numbers you want. Print as desired.

And I assumed, based on your example, you don't care about case, hence the lower() function call. Using Python 3's asterisk splat operator (*) you could do all of this as a one liner; but that I will leave as an exercise for the reader.

A solution is to use the find method in the following way

y="Apples are totally awesome"
    b=0
    for i in range (y.count(o)):
        a=y.find('o' , b)
        print(a)
        b=a+1
    #Returns all the positions of o

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM