1

Below is the list where I want to separate string and integers.

This list gives me correct result:

list_a = ["Michell",123,"Apple","Food",456,"Another"]
list_e = []
x = 0

for item in list_a:
    print("x is: ", x)
    print("item is: ", item)
    if isinstance(item,int):
        list_e.append(item)
        list_a.pop(x)

    x+=1
print(list_a)
print(list_e)

The Problem starts when I add an element to list like below: Added an element 3231 after 456...

>>> list_a = ["Michell",123,"Apple","Food",456,3231,"Another"]
...
['Michell', 'Apple', 'Food', 3231, 'Another']
[123, 456]

What is the problem here?

ShadowRanger
  • 143,180
  • 12
  • 188
  • 271
danny
  • 983
  • 1
  • 7
  • 13

3 Answers3

2

The problem is:

  1. You are iterating over the list as you remove items from it, and
  2. Your counter variable x is not taking into account the positions of removed items.

Try this:

list_a = ["Michell",123,"Apple","Food",456,3231,"Another"]
list_e = []
x = 0

for item in list_a[:]:
    print "x is: ", x
    print "item is: ", item, type(item)
    if isinstance(item,int):
        list_e.append(item)
        list_a.pop(list_a.index(item))

    x+=1
print list_a
print list_e

See also:

(1), (2), (3)

Community
  • 1
  • 1
Nolan Conaway
  • 2,639
  • 1
  • 26
  • 42
  • `list_a.pop(list_a.index(item))` would be simpler as `list_a.remove(item)`, but it would still be wrong if duplicate items are involved. To do it properly, you'd probably want to either rebuild a new `list` (with the value to keep), then replace en masse, or loop in reverse and use `enumerate` to get the precise index for deleting. – ShadowRanger May 11 '17 at 15:36
  • @Nolan You nailed it – danny May 11 '17 at 15:47
0

@NolanConaway should be the accepted answer.

That said, just to show you, if you don't want to use a copy of the list and use pop(), you will have to iterate your list_a starting from the end to avoid your x be out of range. Here is an example:

list_a = ["Michell", 123, "Apple", "Food", 456, 3231, "Another"]
list_e = []

for x, item in reversed(list(enumerate(list_a))):
    print "x is: ", x
    print "item is: ", item, type(item)
    if isinstance(item,int):
        list_e.append(item)
        list_a.pop(x)

print list_a
print list_e

Will output:

x is:  6
item is:  Another <type 'str'>
x is:  5
item is:  3231 <type 'int'>
x is:  4
item is:  456 <type 'int'>
x is:  3
item is:  Food <type 'str'>
x is:  2
item is:  Apple <type 'str'>
x is:  1
item is:  123 <type 'int'>
x is:  0
item is:  Michell <type 'str'>
['Michell', 'Apple', 'Food', 'Another']
[3231, 456, 123]
Kruupös
  • 5,097
  • 3
  • 27
  • 43
0
list_a = ["Michell",123,"Apple","Food",456,3231,"Another"]
numlist=[]             #number list
strlist=[]             #string list

for i in list_a:
    if((type(i))== int):        #to find the data type
        numlist.append(i)

     else:
         strlist.append(i)

print numlist
print strlist

hope this is clear and it works....

Joish
  • 1,458
  • 18
  • 23