Reputation: 7769
How can I get the position of a character inside a string in Python?
Upvotes: 748
Views: 1619032
Reputation: 273756
There are two string methods for this, find()
and index()
. The difference between the two is what happens when the search string isn't found. find()
returns -1
and index()
raises a ValueError
.
find()
>>> myString = 'Position of a character'
>>> myString.find('s')
2
>>> myString.find('x')
-1
index()
>>> myString = 'Position of a character'
>>> myString.index('s')
2
>>> myString.index('x')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: substring not found
string.find(s, sub[, start[, end]])
Return the lowest index in s where the substring sub is found such that sub is wholly contained ins[start:end]
. Return-1
on failure. Defaults for start and end and interpretation of negative values is the same as for slices.
And:
string.index(s, sub[, start[, end]])
Likefind()
but raiseValueError
when the substring is not found.
Upvotes: 955
Reputation: 71
Most methods I found refer to finding the first substring in a string. To find all the substrings, you need to work around.
For example:
vars = 'iloveyoutosimidaandilikeyou'
key = 'you'
def find_all_loc(vars, key):
pos = []
start = 0
end = len(vars)
while True:
loc = vars.find(key, start, end)
if loc is -1:
break
else:
pos.append(loc)
start = loc + len(key)
return pos
pos = find_all_loc(vars, key)
print(pos)
[5, 24]
Upvotes: 1
Reputation: 44585
more_itertools.locate
is a third-party tool that finds all indicies of items that satisfy a condition.
Here we find all index locations of the letter "i"
.
Given
import more_itertools as mit
text = "supercalifragilisticexpialidocious"
search = lambda x: x == "i"
Code
list(mit.locate(text, search))
# [8, 13, 15, 18, 23, 26, 30]
Upvotes: 4
Reputation: 3467
Python has a in-built string method that does the work: index().
string.index(value, start, end)
Where:
def character_index():
string = "Hello World! This is an example sentence with no meaning."
match = "i"
return string.index(match)
print(character_index())
> 15
Let's say you need all the indexes where the character match
is and not just the first one.
The pythonic way would be to use enumerate()
.
def character_indexes():
string = "Hello World! This is an example sentence with no meaning."
match = "i"
indexes_of_match = []
for index, character in enumerate(string):
if character == match:
indexes_of_match.append(index)
return indexes_of_match
print(character_indexes())
# [15, 18, 42, 53]
Or even better with a list comprehension:
def character_indexes_comprehension():
string = "Hello World! This is an example sentence with no meaning."
match = "i"
return [index for index, character in enumerate(string) if character == match]
print(character_indexes_comprehension())
# [15, 18, 42, 53]
Upvotes: 6
Reputation: 222889
Just for a sake of completeness, if you need to find all positions of a character in a string, you can do the following:
s = 'shak#spea#e'
c = '#'
print([pos for pos, char in enumerate(s) if char == c])
which will print: [4, 9]
Upvotes: 191
Reputation: 312
A solution with numpy for quick access to all indexes:
string_array = np.array(list(my_string))
char_indexes = np.where(string_array == 'C')
Upvotes: 0
Reputation: 163
A character might appear multiple times in a string. For example in a string sentence
, position of e
is 1, 4, 7
(because indexing usually starts from zero). but what I find is both of the functions find()
and index()
returns first position of a character. So, this can be solved doing this:
def charposition(string, char):
pos = [] #list to store positions for each 'char' in 'string'
for n in range(len(string)):
if string[n] == char:
pos.append(n)
return pos
s = "sentence"
print(charposition(s, 'e'))
#Output: [1, 4, 7]
Upvotes: 8
Reputation: 2387
Just for completion, in the case I want to find the extension in a file name in order to check it, I need to find the last '.', in this case use rfind:
path = 'toto.titi.tata..xls'
path.find('.')
4
path.rfind('.')
15
in my case, I use the following, which works whatever the complete file name is:
filename_without_extension = complete_name[:complete_name.rfind('.')]
Upvotes: 22
Reputation: 462
What happens when the string contains a duplicate character?
from my experience with index()
I saw that for duplicate you get back the same index.
For example:
s = 'abccde'
for c in s:
print('%s, %d' % (c, s.index(c)))
would return:
a, 0
b, 1
c, 2
c, 2
d, 4
In that case you can do something like that:
for i, character in enumerate(my_string):
# i is the position of the character in the string
Upvotes: 18
Reputation: 83022
string.find(character)
string.index(character)
Perhaps you'd like to have a look at the documentation to find out what the difference between the two is.
Upvotes: 14
Reputation: 342969
>>> s="mystring"
>>> s.index("r")
4
>>> s.find("r")
4
"Long winded" way
>>> for i,c in enumerate(s):
... if "r"==c: print i
...
4
to get substring,
>>> s="mystring"
>>> s[4:10]
'ring'
Upvotes: 60