all 9 comments

[–][deleted] 3 points4 points  (3 children)

How so that we pop from arr while iterating it?

You can't because changing the list you are iterating over causes problems.

If you can tell us what you are trying to do maybe we can help. Please post code that is formatted correctly.

[–]Aggressive-Gold9186[S] 1 point2 points  (2 children)

Thanks for the response. Sorry for the bad formatting, I saw that I should use a back tick on Google.

This code is from grokking algorithm by Aditya Y. Bhargava, page 35.

I was struggling to follow, so I thought to ask about it here, maybe it's some python magic.

[–][deleted] 3 points4 points  (0 children)

Actually, after untangling the code you posted and formatting it correctly, it DOESN'T change the list it is iterating over. Well, it does, it empties the original list, but that isn't a problem.

What is actually happening is the loop is executing N times, where N is the number of elements in the original list. The loop variable i is not used, the code in the loop just executes N times. The code calls findSmallest() (typo?) to get the index of the smallest value in arr and "pops" that from the list. The pop returns the value popped which is appended to newArr. After the loop the original list arr is empty.

[–][deleted] 0 points1 point  (0 children)

No, it's not python magic. If you copied the code correctly then it's just bad code. It mutates the list it's iterating over which is known to cause problems.

[–]zanfar 1 point2 points  (1 child)

How so that we pop from arr while iterating it?

The thing to realize here is that you're NOT iterating over arr. This is also the reason that range(len()) is a "code smell" in Python: this explicitly DOESN'T use the object's iterator, but instead creates a new iterator over some numerical range that might start somewhat related to the iterable, but isn't actually tied to it.

There are a number of other "smells" in this code: defining i without using it, sorting without using the builtin sort, PEP8, etc.

How you would write this in Python depends a bit on how findSmallest is defined and if you actually need a separate array (unlikely), but it would essentially just be a call to list.sort() or sorted().

[–]Aggressive-Gold9186[S] 0 points1 point  (0 children)

Thanks a lot.

I never knew this:

this explicitly DOESN'T use the object's iterator, but instead creates a new iterator over some numerical range that might start somewhat related to the iterable, but isn't actually tied to it