0

I know there have been a lot of questions regarding list comprehensions, but I can't seem to find one that fits my question.

I want to return the index of just one specific character in a list of strings.

char_list = ['H', 'e', 'l', 'l', 'o', ',', ' ', 'W', 'o', 'r', 'l', 'd', '!']

def get_index(c, char_list):
    return [index for index in range(len(char_list)) if c == char_list[index]]

get_index('r', char_list)
# This returns [9] which is what I want. 

This previous list comprehension works to do that, but I want to write an else statement in it to return [-1] if the string passed in isn't present in the list.

I've looked at this question (if else in a list comprehension) and it mentioned a solution which I've tried to write out here:

def get_index(c, char_list):
    return [index if c == char_list[index] else -1 for index in range(len(char_list))]
    
get_index(';', char_list)
# This returns a list equal to the length of char_list 
# returns [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1]
# The else statement before -1 loops through the entire list and makes a list equal in length


# I want to just return [-1].

If I place the else statement at the very end of the list comprehension it raises and error.

How can I place an else statement in my list comprehension such that it would just return [-1] if the character passed in isn't present in the list and [index] if the char is present in the list. Is this possible?

This doesn't take into consideration that more than one count of a specific character could be present in the list. So in some regards it's kind of foolish to make it like this, but I'm interested in practicing list comprehensions

dftag
  • 85
  • 2
  • 8
  • 3
    I wouldn't suggest a list comp for this task as you are searching the whole list when you don't need to. You can use `list.index` with a `try/except` to solve this. – Steven Summers Nov 05 '21 at 02:27
  • If you're just practicing, also look at `enumerate` as it simplifies the whole middle of your comprehension `[i for i, c in enumerate(char_list) if c == 'r']` – Jason S Nov 05 '21 at 02:30
  • Note that `char_list` as you’re using it doesn’t necessarily need to be a list of one-character strings; it can also be just a string instead. – rv.kvetch Nov 05 '21 at 02:30
  • How is `[-1]` more desirable than `[]`? – Kelly Bundy Nov 05 '21 at 03:03

3 Answers3

3

Why are you doing this? there's a built-in function to find the index of an element in a list called index:

char_list = ['H', 'e', 'l', 'l', 'o', ',', ' ', 'W', 'o', 'r', 'l', 'd', '!']
char_list.index('r') -> 9
Pedro Maia
  • 2,666
  • 1
  • 5
  • 20
1

Your list comprehension produces an empty list if there's no match -- so your function just needs to return [-1] in place of an empty list, rather than modifying the way that the list is generated. The or operator is an easy way to return a "default" in place of a falsey value (like an empty list):

>>> def get_index(c, char_list):
...     return [index for index in range(len(char_list)) if c == char_list[index]] or [-1]
...
>>> get_index('r', char_list)
[9]
>>> get_index(';', char_list)
[-1]
Samwise
  • 68,105
  • 3
  • 30
  • 44
1

I wouldn't suggest list comprehension, since a list is not useful here, so use .index method with if statement, to get your output -

char_list = ['H', 'e', 'l', 'l', 'o', ',', ' ', 'W', 'o', 'r', 'l', 'd', '!']

def get_index(c, char_list):
    if c in char_list:
        return char_list.index(c)
    return -1

a = get_index('r', char_list)
print(a)
PCM
  • 2,881
  • 2
  • 8
  • 30