Pollypeptide
Pollypeptide

Reputation: 33

Python2.7 - Incorrect output when iterating through string index and printing only even or odd index value

When iterating through a string and printing only the value of the even string index, Python is printing the value at string.index(3) even though I'm asking it to only print the value if the index is even. I would like to know why this is happening. Here is the code I have been using:

    my_string = 'Hello, World!'
    for i in my_string:
        if my_string.index(i) % 2 == 0:
            print i
        else:
            print my_string.index(i)

When we run the code, it should return:

H
1
l
3
o
5

7
o
9
l
11
!

However, Python is returning:

H
1
l
l 
o
5

7
o
9
l
11
!

As you can see, the 'l' at index[3] is being returned instead of 3.

This seems to be the case in every interpreter I use so I'm assuming it's a problem with Python. Is there some way to fix this? Is it happening for anyone else? This seems like it could be a very big issue if someone is writing a program that needs to separate even and odd indexes accurately.

Upvotes: 1

Views: 83

Answers (4)

SkyWsie
SkyWsie

Reputation: 1

Instead of iterating on the sting itself, try iterating on range(len(my_string)). The full instruction would be: for i in range(len(my_string): This will step every number from 0 to one less than the number of characters in the string. You can then use i to slice your string to get the individual character. You can also use the other the other inputs to the range function to specify where to start (default=0) and step size (default=1).
As for the rest, use i % 2 == 0 in your if statement, print i to print the index, and print my_string[i] to print the character.

Upvotes: 0

Wayne Werner
Wayne Werner

Reputation: 51877

.index doesn't do what you think it does - it returns the first index. In your case you have:

 Hello... # text
 01234    # indices

The first index of l is 2. Which is even, and not displayed. What you want to use instead is enumerate:

my_string = 'Hello, World!'
for i, char in enumerate(my_string):
    if i % 2 == 0:
        print char
    else:
        print i

If you read the docs you'll see that:

s.index(x) | index of the first occurrence of x in s

You can also try this way:

Python 2.7.10 (default, Oct 23 2015, 19:19:21) 
[GCC 4.2.1 Compatible Apple LLVM 7.0.0 (clang-700.0.
Type "help", "copyright", "credits" or "license" for
>>> help('hello'.index)
Help on built-in function index:

index(...)
    S.index(sub [,start [,end]]) -> int

    Like S.find() but raise ValueError when the substring is not found.

(which should lead you to

>>> help('hello'.find)
Help on built-in function find:

find(...)
    S.find(sub [,start [,end]]) -> int

    Return the lowest index in S where substring sub is found,
    such that sub is contained within S[start:end].  Optional
    arguments start and end are interpreted as in slice notation.

    Return -1 on failure.

lowest index in S

In 'Hello, World!' the lowest index for l is 2. The lowest index of o is 4. If you took your code and flipped the logic to if i % 2: then you'll see that you get 4 for the second o!

Upvotes: 4

chepner
chepner

Reputation: 532003

index returns the index of the first occurrence of its argument; l occurs three in Hello, World!, but my_string.index('l') always returns 2.

Use enumerate instead:

for i, c in enumerate(my_string):
    if i % 2 == 0:
        print c
    else:
        print i

Upvotes: 2

This is because .index returns the index of the first matching character (or the start of the first matching substring), not the currently iterated position. Since "Hello" has 2 l characters, the my_string.index('l') will always return 2, and as an even number, the character is printed instead of index.

What you need is the builtin function enumerate, which yields pairs of index, item for each item in the given iterable:

my_string = 'Hello, World!'
for index, char in enumerate(my_string):
    if index % 2 == 0:
        print(char)
    else:
        print(index)

Upvotes: 2

Related Questions