I encountered an interesting and puzzling situation while trying to remove all the empty strings from a list. I wrote the below code the first time.
lst=['###','','@@@','','$$$','','','%%%','','&&&']
print "len:",len(lst)
iteration=1
for item in lst:
print iteration,":",lst,":",len(lst),":","'%s'"%item
if item!='':
pass
else:
lst.remove(item)
iteration+=1
It produces the following output:
len: 10
1 : ['###', '', '@@@', '', '$$$', '', '', '%%%', '', '&&&'] : 10 : '###'
2 : ['###', '', '@@@', '', '$$$', '', '', '%%%', '', '&&&'] : 10 : ''
3 : ['###', '@@@', '', '$$$', '', '', '%%%', '', '&&&'] : 9 : ''
4 : ['###', '@@@', '$$$', '', '', '%%%', '', '&&&'] : 8 : ''
5 : ['###', '@@@', '$$$', '', '%%%', '', '&&&'] : 7 : '%%%'
6 : ['###', '@@@', '$$$', '', '%%%', '', '&&&'] : 7 : ''
NOTE: The code doesn't work like it should. There are some empty strings in the
output.
I later found better ways like:
list comprehensions: [x for x in lst if x!='']
or creating a new list and copying the non empty strings to it, which happens
to be more efficient than the above code because it doesn't involve shifting the
position every time you remove an element from the list.
I however have some questions regarding the output of the code above.
First question is, why doesn't the loop run ten times(the iteration number is on
the far left) because the original length of the list is ten.
Second, if you look at the rightmost column, you realize that it doesn't print
print the @@@
string. It totally skips it!! My theory is that the in
operator
is sugar(most likely) for an index so that even if the length of the list changes
the index keeps increasing by one. This would explain why on the third iteration
the value of i
is the empty string and not the @@@
since lst[2]
is ''
.
Is there something I need to know when using the in operator?