how to modify a list while iterating (intermediate) anthony explains #402

preview_player
Показать описание
*normally* you can't modify a list while iterating over it but I show a little trick that makes it possible. I also show how you might refactor "iterating a dict while modifying" as well!

==========

I won't ask for subscriptions / likes / comments in videos but it really helps the channel. If you have any suggestions or things you'd like to see please comment below!
Рекомендации по теме
Комментарии
Автор

This is a huge throwback, I remember you telling me to iterate backwards back in 2018 when I was running into this exact issue, have never forgotten this strat

I had an interview a couple months back where I told the dude that attempting to remove while iterating could become messy and had to explain why cause he had no idea :p

i love i have these random moments perma locked in memory lmaooo

ianchui
Автор

I learned this trick first from CodingTrain 6 years ago! Still amazes me that this isn't common programming knowledge.

sadhlife
Автор

Personally my first idea was to use a while loop and use an if statement to either remove or indent the index. Iterating backwards is a really interesting solution, I like it.

_scourvinate
Автор

this is a cool solution but I think for lists that aren't sorted and have duplicate values it will still have unexpected behavior because lst.remove will remove first matching value left to right so it could be better to use lst.pop(index) like so:
def delete_zeros(lst):
i = -1
for num in reversed(lst):
if num == 0:
lst.pop(i)
i += 1
i -= 1
return lst

delete_zeros([1, 0, 0, 1, 0, 2, 0, 1, 3])

bartea
Автор

For the dict case, I think it would be more efficient to just iterate over a copy of the dict keys then making a copy of the whole dict:

dct = {v: v for v in range(10)}
print(f"{dct=}")

for k in list(dct.keys()):
if k == 2:
del dct[k]
else:
print(f"{k}: {dct[k]}")

print(f"{dct=}")

palto-ai
Автор

I did this once and i only realized later i wasn't iterating over a copy of the list. I was appending new elements depending on the elements already in the list. That would have to happen to the new elements too until no new elements are appended. In the end this behavior was actually beneficial somehow lol. I can't vouch for the correctness of that alg though. But iirc i managed to pass all the tests that alg had to pass (in a academic exam, let's say).

I guess my problem was different though, 'cuz i think i didn't do any removing.

ludo
Автор

you just solved my problem and in a palatable way. Subscribed. Thanks.

the_foliot
Автор

Few years ago I had a loop that iterated through a set while deleting some elements and it has really chaotic behavior, not even predictable like the list iterator skipping one element

It was hell to debug because it worked normally most of the time, and when I found it I didn't know this was something one shouldn't do so I thought it was some kind of interpreter bug, ended up in the set iterator implementation cpython code and found a nice comment explaining that it would be a really bad idea to modify the set while using the iterator 😅

blumer
Автор

is there any situation where iterating over a list and removing elements from it is a good idea? I was always under the impression that you should never do that

muhammadsarimmehdi
Автор

what about using a pointer to iterate over the list, and if you remove an item, decrement pointer, else increment the pointer. Like so:

it = 0
end = len(list)

while(it < end):
if (condition_is_met):
del list[it]
end -= 1
it -= 1
else:
it += 1

marklagana
Автор

I presume reversing a list also has some overhead, but not much as copying it?

realsuayip
Автор

Using remove() would only work with unique values right? In those cases does enumerating and pop(index) work just as well?

FreestyleRez
Автор

I've started using

for item in list(my_list):
# modify list here

since list() returns a copy of the list.

fabiolean
Автор

Would add to the list while iterating also show some kind of error?

someoneanonymous
Автор

Weird stuff, I must admit it's even weirder than print( condition and true value or false value ) code.

lukajeliciclux
Автор

I was Hoping you would have a trick that doesn’t have space overhead for dict😂

NoProblem
Автор

But reversed also returns a new list, so using list() or reversed() does not matter

lonterel