0

i write a code to separate int from the list

when i write the code that way not working

list_a = [1,2,3,4,5,6,7,8,'Ahmed','Mustafa',100,103,107]
list_b = []

x = 0
for item in list_a:
    if isinstance(item, int):
        list_b.append(item)
        list_a.pop(x)
    x +=1


print (list_a)
print (list_b)
print (x)

and that`s my output

[2, 4, 6, 8, 'Ahmed', 'Mustafa', 103]
[1, 3, 5, 7, 100, 107]
8

and the code work in this way

list_a = [1,2,3,4,5,6,7,8,'Ahmed','Mustafa',100,103,107]
list_b = []
list_d = []

x = 0
for item in list_a:
    if isinstance(item, int):
        list_b.append(item)
    else :
        list_d.append(item)
    x +=1


print (list_a)
print (list_b)
print (list_d)
print (x)

why that glitch happened ?

Muzdava
  • 3
  • 1
  • Whats the output in the second case? – Reaper Feb 06 '17 at 18:07
  • 1
    You're iterating over a list. Modifying the list inside the loop interferes with the iteration. Does anyone have a reference to one of the duplicates for this question? I'm not finding the right search keys today. :-( – Prune Feb 06 '17 at 18:08
  • 1
    You can't `pop` an item while iterating, it changes the size of the iterator. You would have to work off of a copy if you wanted to remove items. – Benjamin Feb 06 '17 at 18:09
  • 1
    Possible duplicate of [Remove items from a list while iterating](http://stackoverflow.com/questions/1207406/remove-items-from-a-list-while-iterating) – Benjamin Feb 06 '17 at 18:11
  • The second code is working fine if you want you can check it [here](http://www.pythontutor.com/live.html#mode=edit) – Kedar Kodgire Feb 06 '17 at 18:11
  • 1
    you can simply store the index for pop to a list and after getting int list pop elements from first using that list of index. – BetaDev Feb 06 '17 at 18:17
  • 1
    use `list(filter(lambda i: isinstance(i, int), list_a))` to get the list of integers – Daniel Puiu Feb 06 '17 at 18:19

1 Answers1

1

Logically

The list pop method pops from an index and removes it. After index 0 is gone, the next index you have to pop is... 0! Since the element in index 0 is gone, the element that should be deleted next has moved to be the new index 0.

Incrementing x every time popped 0 in the first iteration, then 1 (that was the third element in the original list). That's how you lost some elements from being iterated (you simply removed them before they were iterated by the for loop).

Practically

The real problem is the popping itself. When you iterate through an iterable, you should not be modifying it. If you wanted to remove the integers from the original list, have two loops - one for adding the integers to the second list, second to remove them from the first list.

Benjamin
  • 11,560
  • 13
  • 70
  • 119
Yotam Salmon
  • 2,400
  • 22
  • 36