# Finding (multiple) positions of a character in a string

**URL:** <https://forum.freecodecamp.org/t/finding-multiple-positions-of-a-character-in-a-string/268953>\
**Category:** Curriculum Help\
**Tags:** python\
**Created:** [April 3, 2019, 7:34am UTC](https://forum.freecodecamp.org/t/finding-multiple-positions-of-a-character-in-a-string/268953 "2019-04-03T07:34:19Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![hye345](https://sea3.discourse-cdn.com/freecodecamp/user_avatar/forum.freecodecamp.org/hye345/32/112729_2.png) [@hye345](https://forum.freecodecamp.org/u/hye345)\
**Post date:** [April 3, 2019, 7:34am UTC](https://forum.freecodecamp.org/t/finding-multiple-positions-of-a-character-in-a-string/268953/1 "2019-04-03T07:34:19Z")

</div>

I’m trying to code a simple text-based hang-man game, and can’t seem to get over this hump (AKA the middle portion):

```auto
while True:
    from random import randint
    word_list = ['elephant', 'giraffe,', 'snake', 'tiger', 'monkey', 'bird', 'leopard', 'crocodile', 'buffalo', 'mouse', 'wolf', 'pig', 'chicken', 'cheetah', 'hyena', 'shark', 'dolphin', 'lizard', 'whale', 'panda', 'gorilla']
    word_choice = word_list[randint(0,20)]
    word_board = [_] * (len(word_choice))
    chances = 9
    letter_guess = input("Enter a letter. ")
    for letter_guess in word_choice:

    play_again = input("Play again? Press Y or N. ")
    if play_again == "Y":
        continue
    elif play_again == "N":
        print("Ok, bye!")
        break

```

I’m trying to find a way to get the character position of the guessed letter (letter\_guess) in the given word (word\_choice), and have that letter replace the appropriate dash position in the ‘word\_board’ list. I was able to look up the index() and find() methods, but to my understanding, these only return the first instance.

---

<div class="post-metadata">

**Author:** ![chuckadams](https://sea3.discourse-cdn.com/freecodecamp/user_avatar/forum.freecodecamp.org/chuckadams/32/109651_2.png) [@chuckadams](https://forum.freecodecamp.org/u/chuckadams)\
**Post date:** [April 3, 2019, 8:31am UTC](https://forum.freecodecamp.org/t/finding-multiple-positions-of-a-character-in-a-string/268953/2 "2019-04-03T08:31:29Z")

</div>

The `indexOf()` method takes an additional argument, namely the starting position in the string to search from. The sample code on the MDN page below gives an example of using it to find the first and second match. You can adapt this to use a `while` loop to keep finding matches until `indexOf()` returns -1

> **[String.prototype.indexOf()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/indexOf)**
>
> The indexOf() method returns the index within the calling String object of the first occurrence of the specified value, starting the search at fromIndex. Returns -1 if the value is not found.

---

<div class="post-metadata">

**Author:** ![kylec](https://avatars.discourse-cdn.com/v4/letter/k/c4cdca/32.png) [@kylec](https://forum.freecodecamp.org/u/kylec)\
**Post date:** [April 4, 2019, 3:09am UTC](https://forum.freecodecamp.org/t/finding-multiple-positions-of-a-character-in-a-string/268953/3 "2019-04-04T03:09:45Z")

</div>

I answered [a similar question](http://forum.freecodecamp.org/t/replacing-a-specific-value-in-a-dictionary/261452/2?u=kylec) a while back. Hopefully it’s helpful, if not, sorry.

You are correct, `index()` & `find()` return the first occurrence only. If you need to collect all the occurrences of a particular item in an iterable, a `for loop` can easily do that. Even better, Python allows for list comprehensions to condense and speed up these kinds of things.

```auto
# Just demonstrating another Python method for random choice
from random import choice

word_list = ['elephant', 'giraffe,', 'snake', 'tiger', 'monkey', 'bird', 'leopard', 'crocodile', 'buffalo', 'mouse', 'wolf', 'pig', 'chicken', 'cheetah', 'hyena', 'shark', 'dolphin', 'lizard', 'whale', 'panda', 'gorilla']
word_choice = choice(word_list) # Picks a random item from word_list
word_board = ['_' for _ in word_choice] # warm-up
letter_guess = input("Enter a letter. ")
# generates a list of indices for characters matching letter_guess
# list will be empty if no matching characters are found in word_choice
indices_of_guess = [idx for idx, letter in enumerate(word_choice) if letter == letter_guess]

```

---

<div class="post-metadata">

**Author:** ![hye345](https://sea3.discourse-cdn.com/freecodecamp/user_avatar/forum.freecodecamp.org/hye345/32/112729_2.png) [@hye345](https://forum.freecodecamp.org/u/hye345)\
**Post date:** [April 4, 2019, 4:49am UTC](https://forum.freecodecamp.org/t/finding-multiple-positions-of-a-character-in-a-string/268953/4 "2019-04-04T04:49:53Z")

</div>

Thanks. I did end up using a combo for loop and if statement, with the range() function. I just recently learned about list comprehension, still getting the hang of enumeration… kinda hard to read all on one line, maybe it takes time to sink in haha.

Here is the finished code:

```auto
while True:
  from random import randint
  word_list = ['elephant', 'giraffe,', 'snake', 'tiger', 'monkey', 'bird', 'leopard', 'crocodile', 'buffalo', 'mouse', 'wolf', 'pig', 'chicken', 'cheetah', 'hyena', 'shark', 'dolphin', 'lizard', 'whale', 'panda', 'gorilla']
  word_choice = word_list[randint(0,20)]
  word_board = ['_'] * (len(word_choice))
  chances = 9
  letters_played = []
  print(word_board)
  while chances > 0:
    letter_guess = input("Enter a letter. ")
    if letter_guess in letters_played:
      print("Letter already played, please choose another letter. ")
      print(word_board)
      continue
    if letter_guess in word_choice:
      for x in range(len(word_choice)):
        if word_choice[x] == letter_guess:
          word_board[x] = letter_guess
          letter_count = word_choice.count(letter_guess)
      print(f"Yes, {letter_count} {letter_guess}")
      print()
      print(word_board)
      letters_played.append(letter_guess)
    if letter_guess not in word_choice:
      chances = chances - 1
      print("Sorry, that letter isn't here!")
      print(f"You have {chances} chances!")
      print()
      print(word_board)
      letters_played.append(letter_guess)
    if chances == 0:
      print("Sorry, you lost!")
      break
    if '_' not in word_board:
      print("Contragulations, you won!")
      break
  play_again = input("Play again? Press Y or N. ")
  if play_again == "Y":
    print()
    continue
  elif play_again == "N":
    print("Ok, bye!")
    break

```

Much cleaner than the original version, where I used 2 if statements for 2 separate find() methods. Also added a letters-played list, to give message for letters entered twice.

I do have another question though: the word\_board list, I can’t seem to get it to show the blank characters (currently ‘\_’) as blank dashes, like in actual hangman. I guess \_ is a special character in Python, but is there any other way to go about this?

---

<div class="post-metadata">

**Author:** ![chuckadams](https://sea3.discourse-cdn.com/freecodecamp/user_avatar/forum.freecodecamp.org/chuckadams/32/109651_2.png) [@chuckadams](https://forum.freecodecamp.org/u/chuckadams)\
**Post date:** [April 4, 2019, 9:36am UTC](https://forum.freecodecamp.org/t/finding-multiple-positions-of-a-character-in-a-string/268953/5 "2019-04-04T09:36:28Z")

</div>

Silly me, I answered the question for javascript, not python. In python, just use a regular expression and the `.finditer` function. For example:

```python
>>> import re
>>> o = re.compile('o')
>>> foo = 'foobarbazmumblefrotz'
>>> [m.span()[0] for m in re.finditer(o, foo)]
[1, 2, 17]

```

---

<div class="post-metadata">

**Author:** ![kylec](https://avatars.discourse-cdn.com/v4/letter/k/c4cdca/32.png) [@kylec](https://forum.freecodecamp.org/u/kylec)\
**Post date:** [April 4, 2019, 8:47pm UTC](https://forum.freecodecamp.org/t/finding-multiple-positions-of-a-character-in-a-string/268953/6 "2019-04-04T20:47:22Z")

</div>

Haha no, list comprehensions are kinda weird. The one-liner syntax they use has been called “un-Pythonic” more than once. They do provide a non-trivial performance boost under-the-hood when compared to `for...append()` loops however (not that it probably matters here).

I’m not quite sure I understand the question. You’re currently using ASCII character 95, “\_”, what character are you trying to use?  
For string formatting purposes, the `\` character can be used in Python to “escape” the string for special characters, but I’m not sure that’s what you want. Normally Python is pretty willing to print whatever character you want unless you use the “escape” `\` to specifically tell it a character in a string is a special character. Ex: `"\n", "\r", "\t", "\\", "\'", "\""`

Python Shortcuts:

- character-to-code `-->` `ord('some_character')`
- code-to-character `-->` `chr(some_number)`

---

<div class="post-metadata">

**Author:** ![hye345](https://sea3.discourse-cdn.com/freecodecamp/user_avatar/forum.freecodecamp.org/hye345/32/112729_2.png) [@hye345](https://forum.freecodecamp.org/u/hye345)\
**Post date:** [April 5, 2019, 3:46am UTC](https://forum.freecodecamp.org/t/finding-multiple-positions-of-a-character-in-a-string/268953/7 "2019-04-05T03:46:33Z")

</div>

So basically, like the real hang-man game, I want dashes to represent the word; as the player guesses correctly, the dashes are replaced by words. That way, the player has a relative idea of where each letter is supposed to go. Like \_ \_ \_ \_ d \_ \_ f \_ \_.

Until recently, I was only able to print out a list composing of underscores. Unfortunately, this also meant that when it shows on the screen, each underscore has a pair of ‘’ around it, like ‘\_’. It’s just not aesthetically pleasing.

After much googling, I discovered the .join function, whereas one could convert/combine lists into a string.

Here is the updated code:

```auto
while True:
  from random import randint
  word_list = ['elephant', 'giraffe,', 'snake', 'tiger', 'monkey', 'bird', 'leopard', 'crocodile', 'buffalo', 'mouse', 'wolf', 'pig', 'chicken', 'cheetah', 'hyena', 'shark', 'dolphin', 'lizard', 'whale', 'panda', 'gorilla']
  word_choice = word_list[randint(0,len(word_choice))]
  word_board = ['_'] * (len(word_choice))
  chances = 9
  letters_played = []
  print(" ".join(word_board))
  while chances > 0:
    letter_guess = input("Enter a letter. ")
    if letter_guess in letters_played:
      print("Letter already played, please choose another letter. ")
      print(" ".join(word_board))
      continue
    if letter_guess in word_choice:
      for x in range(len(word_choice)):
        if word_choice[x] == letter_guess:
          word_board[x] = letter_guess
          letter_count = word_choice.count(letter_guess)
      print(f"Yes, {letter_count} {letter_guess} \n")
      print(" ".join(word_board))
      letters_played.append(letter_guess)
    if letter_guess not in word_choice:
      chances -=1 
      print("Sorry, that letter isn't here!")
      if chances == 0:
        print("Sorry, you lost! \n")
        break
      print(f"You have {chances} chances! \n")
      print(" ".join(word_board))
      letters_played.append(letter_guess)
    if '_' not in word_board:
      print("Contragulations, you won! \n")
      break
  play_again = input("Play again? Press Y or N. \n")
  if play_again == "Y":
    continue
  elif play_again == "N":
    print("Ok, bye!")
    break

```

---

<div class="post-metadata">

**Author:** ![ILM](https://sea3.discourse-cdn.com/freecodecamp/user_avatar/forum.freecodecamp.org/ilm/32/363239_2.png) [@ILM](https://forum.freecodecamp.org/u/ILM)\
**Post date:** [February 17, 2021, 5:37pm UTC](https://forum.freecodecamp.org/t/finding-multiple-positions-of-a-character-in-a-string/268953/8 "2021-02-17T17:37:23Z")

</div>


