Error in loops, new to Python - Printable Version +- Python Forum (https://python-forum.io) +-- Forum: Python Coding (https://python-forum.io/forum-7.html) +--- Forum: Homework (https://python-forum.io/forum-9.html) +--- Thread: Error in loops, new to Python (/thread-2890.html) |
RE: Error in loops, new to Python - nilamo - Apr-24-2017 Maybe because you're only modifying things you've already iterated over. Regardless, you probably shouldn't do it, and you definitely shouldn't rely on it working right all the time. In this case, you don't need to (since you only iterate over the list once, and do the same thing with every value in the list regardless of what that value is), and for the same reason, you also don't need a while loop, since it'll only ever run once anyway. RE: Error in loops, new to Python - volcano63 - Apr-24-2017 (Apr-24-2017, 03:43 AM)nilamo Wrote: Modifying a list while you're in the middle of iterating over that same list is very dangerous.Usually - from the last time I SNAFUed this way (several years ago ) - iterator skips element on each deletion. It's not dangerous - it's a bug (Apr-23-2017, 10:19 AM)smbx33 Wrote: I made minor modifications to the existing code and provided explanation.Though it works - as I have pointed out in previous post, deleting an element of a list while iterating over that list is a bug, which is in this case accidentally compensated for by the external loop. In another scenario, it will not work as expected This solves the issue while list_: s += list_[0] ..... list_.pop(0)This way you always process first element of the list - while list is not empty, and you don't perform any unnecessary actions RE: Error in loops, new to Python - wavic - Apr-24-2017 Iterate over the copy of the list while modifying the original. for element in list_[:]: # modify list_ RE: Error in loops, new to Python - nilamo - Apr-24-2017 I think the easy solution is to just iterate over a copy of the list, ie: for x in some_list[:]: , but then if the list is large (or is a generator and doesn't exist fully yet), that could just eat memory. Maybe for x in (item for item in some_list): ? That way you can modify the original list, without changing how you iterate. Could make for confusing results sometimes, though.
RE: Error in loops, new to Python - wavic - Apr-24-2017 No problem with the big lists: for element in iter(list_[:]): # do something RE: Error in loops, new to Python - volcano63 - Apr-24-2017 I think a little illustration is in order to show the folly of removing an element from a list while iterating over it. In [1]: l = list(range(10)) In [2]: for elem in l: ...: l.remove(elem) ...: print(elem) ...: 0 2 4 6 8And this shows how OP's code worked In [4]: while l: ...: for elem in l: ...: l.remove(elem) ...: print(elem) ...: 0 2 4 6 8 1 5 9 3 7 RE: Error in loops, new to Python - zivoni - Apr-24-2017 (Apr-24-2017, 06:41 PM)volcano63 Wrote:For me it looks like appropriate behaviour - from my understanding list iterator (created with for clause) only keeps information about list object and current index. For i-th loop it gives i-th item from the actual list - and if in i-th loop i-th item is different than i-th item before start of loop, well, its not for/iterator problem, but yours. So if you are removing items from the start of the list while looping over it, it looks like it skips every second item, while if you are removing items from the end of the list, it looks like iteration over first half of the list only. Indeed it makes things rather confusing , so its bettter to avoid it...(Apr-24-2017, 03:43 AM)nilamo Wrote: Modifying a list while you're in the middle of iterating over that same list is very dangerous.Usually - from the last time I SNAFUed this way (several years ago ) - iterator skips element on each deletion. It's not dangerous - it's a bug (Apr-24-2017, 06:47 PM)nilamo Wrote: I think the easy solution is to just iterate over a copy of the list, ie:Such generator expression would not work, it references original list too, changes would "propagate". RE: Error in loops, new to Python - volcano63 - Apr-24-2017 (Apr-24-2017, 07:50 PM)zivoni Wrote:Let me clarify - I was not talking about the interpreter behavior; I was referring specifically to implementation - that using iterator that way is a bug in the implementation. I thought that it was rather obvious(Apr-24-2017, 06:41 PM)volcano63 Wrote: Usually - from the last time I SNAFUed this way (several years ago ) - iterator skips element on each deletion. It's not dangerous - it's a bugFor me it looks like appropriate behaviour - RE: Error in loops, new to Python - smbx33 - Apr-24-2017 Thank you all, I have a deeper understanding of why I was wrong in deleting items off the same list that I am iterating over :P Even though its a bug and gives undesired results(sometimes). Since it was my very first time using remove() as a function, I was very content watching the desired results populate. I now know that if you are removing items from the start of the list while looping over it, it looks like its skips an item, but even if the item is skipped, the while loop will just tell it to iterate again until no items on the list. But that the practice is still confusing and should be avoided. RE: Error in loops, new to Python - nilamo - Apr-24-2017 >>> items = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] >>> for ndx, item in enumerate(items): ... print("{0} => {1}".format(ndx, item)) ... items.remove(item) ... 0 => 0 1 => 2 2 => 4 3 => 6 4 => 8 5 => 10 >>> items [1, 3, 5, 7, 9]The for loop keeps track of what index it's at, but when you change the underlying list, the index stays the same... it's just going to refer to a different element. So you don't iterate over the whole list, but it is at least predictable. Predictable, at least, if that's what you were expecting. I still think you either shouldn't modify the list, or use a while loop and only ever use the first element. |