Code works only sometimes for removing odd or even index items

Question:

Question :​ Write a Python program to remove the characters which have odd or even index
values of a given string.

  1. I tried to make a copy of the list by deep copy .
  2. I ran a loop from first list and checked for even then used pop method on second list to remove that specific index from the second list .

This code works for some inputs , I think mostly for those which doesn’t have any repeated characters and doesn’t work for others.

Code

#!/usr/bin/python3
import copy
list1 = input("Enter a string ")
list1 = list(list1)
list2 = copy.deepcopy(list1)
for i in list1:
    if list1.index(i)%2 != 0:
        list2.pop(list2.index(i))
print(list2)

The outputs for some samples are :

123456789 -> ['1', '3', '5', '7', '9'],   qwertyuiop -> ['q', 'e', 't', 'u', 'o'],   saurav -> ['s', 'u'],   11112222333344445555 -> ['1', '1', '1', '1', '2', '2', '2', '2', '3', '3', '3', '3', '4', '4', '4', '4', '5', '5', '5', '5']
Asked By: Saurav Raj Joshi

||

Answers:

Read the documentation for index. It returns the index of the first occurrence of the given value. A simple print inside the loop will show you what’s going on, in appropriate detail. This is a basic debugging skill you need to learn for programming in any language.

import copy
list1 = input("Enter a string ")
list1 = list(list1)
list2 = copy.deepcopy(list1)
for i in list1:
    if list1.index(i)%2 != 0:
        print(i, list1.index(i), list2.index(i))
        list2.pop(list2.index(i))
        print(list2)
print(list2)

output:

Enter a string google
o 1 1
['g', 'o', 'g', 'l', 'e']
o 1 1
['g', 'g', 'l', 'e']
e 5 3
['g', 'g', 'l']
['g', 'g', 'l']

… and that’s your trouble. Fix your logic. You already know the needed index to save or remove. There is no need to extract the character, and then search for it again. You already know where it is.

Even better, simply slice the original string for the characters you want:

print(list1[::2])
Answered By: Prune

Your problem is the list.index function. The documentation states that it "returns zero-based index in the list of the first item whose value is equal to x." Because you are calling it on list1 – and that is not modified – the result will always be list1.index('a') == 1 for example.

The correct solution would be to use enumerate. A further problem exists here – because you are indexing from an array that you have not modified, you indexes will be off after the first list.pop operation. Every item after the one removed will have been shifted by 1. To correct this, you could instead try building a list instead of emptying one:

#!/usr/bin/python3
list1 = input("Enter a string ")
list2 = []
for i, item in enumerate(list1):
    if i % 2 == 0:
        list2.append(item)
print(list2)
Answered By: Kendas

You don’t need to iterate at all. Just reference the string elements directly.

st="123456789"
print('Odd: ', list(st[::2]))
print('Even: ', list(st[1::2]))

Output:

Odd:  ['1', '3', '5', '7', '9']
Even:  ['2', '4', '6', '8']
Answered By: LevB

The method list.index(i) returns index in the list of the first item whose value is equal to i.

For example, "saurav".index('a') returns 1. when you call list2.pop(list2.index(i)) and you want to pop an a, it doesn’t work well.

I think it can be simple using range as build-in function.

list1 = list(input("Enter a string "))
list2 = list()
for i in range(len(list1)):
    if i % 2 == 0:
        list2.append(list1[i])
print(list2)

It works with same way by following:

list1 = list(input("Enter a string "))
list2 = list()
for i in range(0, len(list1), 2):
    list2.append(list1[i])
print(list2)

Also, you can use Extended Slices in Python 2.3 or above.

list1 = list(input("Enter a string "))
list2 = list1[::2]
print(list2)
Answered By: Joona Yoon
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.