# Can I use `index()` for the loop challenge?

the solution to this challenge was quite straight forward, but i did it the stupid way using .index():

``````#Write your function here
def odd_indices(lst):
new_lst = []
for item in lst:
if lst.index(item)%2==1:
new_lst.append(item)
return new_lst

#Uncomment the line below when your function is done
print(odd_indices([4, 3, 7, 10, 11, -2]))
``````
5 Likes

No way is âstupidâ though some do come with provisos and gotchas. `list.index()` has one of its own. What if there are duplicates in the list? `.index()` will only ever find the first one. In this exercise we wouldnât need to know the index in this way.

We know that a list has a sequential index starting at `0`. Zero is even so we would want to start one space over, with `1`. Next we go to `3`, then `5`, then `7`, and so on, in steps of 2. Sounds like a job for `range` since it can be started and stopped anywhere, and we can step in any stride length.

``````range(1, len(lst), 2)
``````

After that itâs just a matter of appending the value at the current index to the return list. No `if`'s about it.

11 Likes

when you look at it from that perspective , it makes complete sense!
much love for the detailed explanation <3

1 Like

Hi is there a way to check what position an index has in a list? i was trying to do it with %2 != 0 method

We can use the `.index()` method if we are sure there is but one item, and no duplicates since this method will only return the index of the first item it finds.

``````>>> a = [2,5,8,9,3,2,5,8]
>>> a.index(8)
2
>>>
``````

Unless we spin off a shortened slice, we will not get to the other `8`.

``````>>> b = a[a.index(8)+1:]
>>> b.index(8)
4
>>>
``````

We do have a tool that we can use to find all the indices, but it will take some reckoningâŚ

``````>>> c = [i for i, x in enumerate(a) if x == 8] # i is the index, x the item
>>> c
[2, 7]
>>>
``````
1 Like
``````def odd_indices(lst):
return [elem for elem in lst if lst.index(elem) % 2 != 0]
``````

If I do it this way will it not also cover the edge cases like when there are 2 same elements?

Never mind. Itâs basically the same thing as the example that started this thread and I think I understand the problem now. The range function makes more sense in this case. Thank you!

I just recently starting using these help/question things and my god. I would just like to say that this mtf guy is SOOOOO HELPFUL! Without this guy I would be in a state âvexationâ
Sometimes I feel like they just throw you in some deep waters after guiding you in the shallow end. But thank you mtf guy! I was ready to give up in frustration but knowing thereâs accecible help to guide me through the complicated parts is very helpful,

2 Likes

Iâm not quite sure that this is true in <for â in> example:

What if there are duplicates in the list? `.index()` will only ever find the first one.

i wrote:

``````def odd_indices(lst):
new_list = [new_index for new_index in lst if lst.index(new_index) % 2 == 1]
return new_list
``````

and it worked just fine with sequences like `[4, 3, 7, 10, 11, -2]` or (with dublicates) `[4, 3, 7, 3, 11, -2]`
Or am i just not seeing something important?

Python List index() returns smallest index of element in list

Consider,

``````>>> u = [1,2,3,4,5,6,7,8,9,1,2,3,4,5,6,7,8,9]
>>> [x for x in u if u.index(x) % 2 == 1]
[2, 4, 6, 8, 2, 4, 6, 8]
>>>
``````

What should be in the return list?

``````[1,2,3,4,5,6,7,8,9,1,2,3,4,5,6,7,8,9]
^   ^   ^   ^   ^   ^   ^   ^   ^
``````

The error is caused by using `.index()`.

Now consider,

``````>>> [u[x] for x in range(1, len(u), 2)]
[2, 4, 6, 8, 1, 3, 5, 7, 9]
>>>
``````

So why then it skips 9-th idex? 10-th idex isnât the smallest. What i see is that for some reason it has âoddâ behaviour with odd numbers. For examle if we replace first 4 with 7 itâll output `[2, 7, 6, 7, 8, 2, 6, 7, 8]` and now it includes 6-th idex still excludes 9-th index, exludes 11, 12, 13-th and 17-th indexes.
Sorry, i am very confused right now, i canât help it with this issue )

The first error there is caused by index the second time the value 1 appears which as you correctly state is the 9th index. So what happens in the if expression used in our comprehension:

``````if u.index(x) % 2 == 1
``````

So what does `u.index(x)` actually evaluate to for index `[9]`? Since the value at index 9 is an integer 1 we have `u.index(1)`. Print it and see but youâll find it equals 0. Does `0 % 2 == 1`? No it does not. So we skip this value despite the fact itâs actually in a position we wanted to return. Thatâs a problem. This problem continues with further elements of the list.

A blunt example of index only returning the first matching element-

``````# idx=( 0    1    2    3    4    5 )  # Included only to show the index of the list.
lst = ['a', 'b', 'a', 'b', 'a', 'b'].index('b')  #
# .index('b') will only ever supply an index of 1
# we can only find the first appearance using just .index()
``````

Using just `.index` we have completely ignored the values of âbâ at index 3 and and index 5.

1 Like

Ok, i think i understand it now. Even if there are other flaws that came up with changing 4 with 7.
Think i need to come back here another time.
Anyways, Thank You for the explanation !

1 Like