[Python] string parsing, locating specific chars

Started by
11 comments, last by glBender 16 years, 11 months ago
In python, how can I get the position of every character x in a string? string.find and string.index seem to find the first instance, I want a list of all of them. For example, given the string "Hello World" and the character 'l', I would want [3,4,10]. Are there any built in functions that can do this? Or a simple way?
Advertisement
Nevermind, my god I love python! Sorry for even asking...

def contains(string,char):    list = []    for i in range(0,len(string)):        if string == char:            list = list +     return list
A more idiomatic (and shorter!) way would be using a list comprehension:
def indices(string, char) :  return <br><br></pre></div><!–ENDSCRIPT–><br><br>EDIT: Another &#111;ne, just for fun:<br><!–STARTSCRIPT–><!–source lang="python"–><div class="source"><pre><br><span class="vb-keyword">def</span> indices(string, char) :<br>  <span class="vb-keyword">return</span> filter(<span class="vb-keyword">lambda</span> i: string<span style="font-weight:bold;"> == char, range(<span class="cpp-number">0</span>, len(string)))<br><br></pre></div><!–ENDSCRIPT–> 
I'm used to writing simple, structured, code in c++... and I have to say that both of those you posted are... I need practice.
Different language, different idioms :)

Anyway, in C++, an explicit loop would probably be the cleanest solution, although one *might* be tempted to write something like:

#include <string>#include <vector>#include <boost/iterator/counting_iterator.hpp>#include <boost/lambda/lambda.hpp>std::vector<int> indices(std::string str, char ch){  using namespace boost;  std::vector<int> result;  remove_copy_if(counting_iterator<int>(0),                  counting_iterator<int>(str.size()),                 back_inserter(result),                 lambda::var(str)[lambda::_1] != ch);  return result;}


(Yes, it works. No, it's not pretty :P)
Quote:
Original post by Sharlin
A more idiomatic (and shorter!) way would be using a list comprehension:
def indices(string, char) :  return </pre><br><!–QUOTE–></td></tr></table></BLOCKQUOTE><!–/QUOTE–><!–ENDQUOTE–><br><br>Instead of range you can use enumerate which returns pairs of (index,value):<br><!–STARTSCRIPT–><!–source lang="python"–><div class="source"><pre><br><span class="vb-keyword">def</span> indices(string, char):<br>  <span class="vb-keyword">return</span> <br><br></pre></div><!–ENDSCRIPT–><br><br>
Ooh, nice! I wondered if there was something like that. Now it really reads like pseudocode :)
python just amazes me sometimes. It's perfect for stuff like this.
string.find and string.index both take start and end indices within which to search (they behave like slices).

Strings are also iterable in Python, so if you merely wish to iterate over the elements (letters) of the string:
for c in string:    ...
Quote:Original post by Oluseyi
string.find and string.index both take start and end indices within which to search (they behave like slices).

Strings are also iterable in Python, so if you merely wish to iterate over the elements (letters) of the string:
for c in string:    ...


Yeah, thats what I was doing originally and why I had problems, because I wanted to get the position of each occurence of the char, and iterating just told me I had found the occurence, not where it was.

This topic is closed to new replies.

Advertisement