-1

I have a list of strings: ['1','2','3','4','5','6','7','8','9']. I tried to convert the list of strings to integers using "for loop". But to my utter surprise and shock, the list contained alternate strings and integers data types.

I tried out for various sizes of lists, and every time it was that the alternate entries got converted.

listt=['1','2','3','4','5','6','7','8','9']
for x in listt:
    if type(x)==str:            #So that the integer already converted does not enter into loop
        intx=int(x)
        listt.append(intx)
        listt.remove(x)
    else:
        continue
print(listt)

EXPECTATION: [1, 2, 3, 4, 5, 6, 7, 8, 9]

REALITY: ['2', '4', '6', '8', 1, 3, 5, 7, 9]

4 Answers4

4

Modifying the list you're iterating over (append/remove etc) is never a good idea. Instead create a new list:

numberlikes = ['1', '2', '3', '4', '5', '6', '7', '8', '9']
integers = []
for num in numberlikes:
    integers.append(int(num))
print(integers)

which gives:

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

as you'd expect

abdusco
  • 9,700
  • 2
  • 27
  • 44
  • But tell me, my dear abdusco, what is wrong with my code. Thanks. – Shiladitya Mukherjee Jul 01 '19 at 17:11
  • When you remove `'1'`, the next value `'2`' replaces its position and when the iterator looks for the next element, it finds `'3'`. So, alternate elements are getting skipped because of list modifying operations within the loop on the list. – Abhineet Gupta Jul 01 '19 at 17:14
  • 1
    @ShiladityaMukherjee Say `x = '1'`, make it an int, and remove it from the list, you get `['2', '3', '4', ..., 1]`. Now in the next iteration `x = '3'` because the for loop wants to read the second item in the list and your list becomes `['2', '4', '5', ..., 1, 3]` and it continues like this. – abdusco Jul 01 '19 at 17:16
  • Thanks a TON Abhineet Gupta and abdusco. I now understand the mechanism of 'for loop' completely. – Shiladitya Mukherjee Jul 01 '19 at 17:22
1

You could just create a new list as:

newlist = [int(x) for x in listt if type(x) == str]

And if you are looking for your mistake is here: listt.remove(x)

you shoud not remove values from the list on which you are iterating

Matteo Peluso
  • 452
  • 1
  • 6
  • 23
  • I do not understand how "removing values from the list on which you are iterating" creates any problem. When I executed the code manually, it seemed fine. Can you please clarify? – Shiladitya Mukherjee Jul 01 '19 at 17:15
  • think about this case for example: `listt=['1','2','3','3','1','4','5','6','7','8','9'] for index, value in enumerate(listt): print(listt) listt.remove(value) ` you would remove duplicate values from the list before transforming it to integers. – Matteo Peluso Jul 01 '19 at 17:18
  • Yeah your problem is valid too. Thanks! Also refer to abdusco's answer! – Shiladitya Mukherjee Jul 01 '19 at 17:23
0
listt=['1','2','3','4','5','6','7','8','9']
for i in range(len(listt)):
    x= listt[i]
    if type(x)==str:            #So that the integer already converted does not enter into loop
        intx=int(x)
        listt[i]=intx
    else:
        continue
print(listt)

Check this Or use lamda function

listt=['1','2','3','4','5','6','7','8','9']
listt = [int(x) for x in listt]
print(listt)
ma_dev_15
  • 1,176
  • 7
  • 18
0

Consider this example

mylist = [*'123']
for x in mylist:
    print(x)
    mylist.remove(x)

print(mylist)

Producing this

1
3
['2']

As you iterate over a mutable object (like a list) and remove stuff WHILE you're iterating over it... you WILL mess stuff up.

In your case, you removed an object while Python is trying to keep track of where it's at. It then thinks that what was going to be the next object is now the object prior. So instead of getting that next object, it skips it. This creates the alternating pattern you are seeing.

Solution

DON'T DO THAT!

Helpful Solution

[*map(int, mylist)]

[1, 2, 3]
piRSquared
  • 285,575
  • 57
  • 475
  • 624