user3329732
user3329732

Reputation: 343

Confused by output from simple Python loop

I have a list of items and want to remove all items containing the number 16 (here a string, ind='16'). The list has six items with '16' in and yet my loop consistently only removes five of them. Puzzled (I even ran it on two separate machines)!

lines=['18\t4', '8\t5', '16\t5', '19\t6', '15\t7', '5\t8', '16\t8', '21\t8', '20\t12', '22\t13', '7\t15', '5\t16', '8\t16', '21\t16', '4\t18', '6\t19', '12\t20', '8\t21', '16\t21', '13\t22']

ind='16'

for query in lines:
    if ind in query:
        lines.remove(query)

Subsequently, typing 'lines' gives me: ['18\t4', '8\t5', '19\t6', '15\t7', '5\t8', '21\t8', '20\t12', '22\t13', '7\t15', '8\t16', '4\t18', '6\t19', '12\t20', '8\t21', '13\t22']

i.e. the item '8\t16' is still in the list???

Thank you

Clive

Upvotes: 0

Views: 47

Answers (2)

Hackaholic
Hackaholic

Reputation: 19763

Note: Never modify list while looping

lines=['18\t4', '8\t5', '16\t5', '19\t6', '15\t7', '5\t8', '16\t8', '21\t8', '20\t12', '22\t13', '7\t15', '5\t16', '8\t16', '21\t16', '4\t18', '6\t19', '12\t20', '8\t21', '16\t21', '13\t22']
ind = '16'
new_lines = [ x  for x in lines if ind not in x ]

Upvotes: 1

chepner
chepner

Reputation: 532303

It's a bad idea to modify the list you are iterating over, as removing an item can confuse the iterator. Your example can be handled with a simple list comprehension, which just creates a new list to assign to the original name.

lines = [query for query in lines if ind not in query]

Or, use the filter function:

# In Python 2, you can omit the list() wrapper
lines = list(filter(lambda x: ind not in x, lines))

Upvotes: 2

Related Questions