+ 3

Why Answer is not 3 3 3 3?

What is the output of this code? a=[0,1,2,3] for a[-1] in a: print(a[-1])

5th May 2023, 4:38 AM
Dadaxon Xudayberganov 👑 🇺🇿🇺🇿
Dadaxon Xudayberganov 👑 🇺🇿🇺🇿 - avatar
25 ответов
+ 4
ok, idk if you care but I wasn't really satisfied with my previous answer, so I've done some deep digging and here's what's happening to cause the 0 1 2 2 pattern: for X in Y: -- takes each element in Y and creates an "iterable" object (structurally like a list, but functionally distinct) with each of those same elements in it. Then it takes the next element of the iterable, assigns it to X, and performs the operations specified in the for loop. Repeat until the next element doesn't exist. So, what "for a[-1] in a" does is: 1. make an iterable containing a[0], a[1], a[2], a[3] 2. set a[-1] = a[0] (which is 0) 3. perform print(a[-1]) (prints 0) 4. set a[-1] = a[1] (which is 1) 5. perform print(a[-1]) (prints 1) 6. set a[-1] = a[2] (which is 2) 7. perform print(a[-1]) (prints 2) 8. set a[-1] = a[3] (which is still 2, from step 6) 9. perform print(a[-1]) (prints 2) result: 0 1 2 2 So if you care, that's why it failed in the precise way that it did.
5th May 2023, 8:11 AM
Orin Cook
Orin Cook - avatar
+ 3
Orin Cook Yes. Pls check out another example of a Python for loop altering the iterator, and see how this immediately affects each iteration. https://code.sololearn.com/cNJHu2llACej/?ref=app
5th May 2023, 5:53 PM
Emerson Prado
Emerson Prado - avatar
+ 2
Hey well you started the for loop with the last entry excluded so your output will be 0,1,2,2. What you try to do ? If you wanna try access the last element than you need a[3] instead[-1]
5th May 2023, 4:49 AM
S3R43o3
S3R43o3 - avatar
+ 1
when you iterate through a list like this, use a fresh, generic variable for your index. I'm not sure what you thought you were doing there, but in the line: for a[-1] in a: just replace a[-1] with a new, unused variable name. it can he x, it can be i, or it can even be literally_anything_else, as I typed above, and it'll work. btw, S3R43o3 : python allows negative indexing of lists to count backwards from the end, so a[-1] is valid. I hate it, but it's valid.
5th May 2023, 5:56 AM
Orin Cook
Orin Cook - avatar
+ 1
Orin Cook Python for loops don't do lazy evaluation. The reason a[3] yields 2 instead of 3 is that it was assigned 2 in the previous iteration - since a[-1] is the loop variable.
5th May 2023, 3:40 PM
Emerson Prado
Emerson Prado - avatar
+ 1
Dadaxon Xudayberganov 🇺🇿🇺🇿🇺🇿 Orin Cook you're modifying a as you iterate through it. iterating through a and assigning the value to a[-1] at each pass. you can introspect what's happening: a=[0,1,2,3] print('before: ', a) for a[-1] in a: print('inside: ', a) print('a[-1]: ', a[-1]) print('final: ', a) Normally, a for-in loop in Python would not modify the list, but putting the list itself as the iterator changes the behavior since the values are assigned back to the list. So I would probably say it's a case of self-reassignment.
6th May 2023, 3:45 AM
Bob_Li
Bob_Li - avatar
+ 1
Orin Cook In the case of lazy evaluation, shouldn't the result be [0, 0, 1, 2, 3]?
6th May 2023, 5:08 AM
Emerson Prado
Emerson Prado - avatar
+ 1
Dadaxon Xudayberganov 🇺🇿🇺🇿🇺🇿 if you want 3 3 3 3 use a = [0,1,2,3] for _ in a: print(a[-1], end=' ')
6th May 2023, 11:14 AM
Bob_Li
Bob_Li - avatar
+ 1
Emerson Prado no, because index is the *contents of* the nth element in the last. In fact it would probably throw an error if it were eager (python doesn't let you do that, at least not in the Playground), but since it's lazy, by the time it checks the final value it's already 2, not 3. So it changes [2+1] on the final iteration. That said, you did give me an idea for making it more obvious that it's lazy, so go look at the revised code above. Remove the index != 4 condition if you wanna see it go forever lol
6th May 2023, 12:34 PM
Orin Cook
Orin Cook - avatar
0
for literally_anything_else in a:
5th May 2023, 5:30 AM
Orin Cook
Orin Cook - avatar
0
I don't understand 😞
5th May 2023, 5:40 AM
Dadaxon Xudayberganov 👑 🇺🇿🇺🇿
Dadaxon Xudayberganov 👑 🇺🇿🇺🇿 - avatar
0
PS: my understanding is that it actually generates the iterable lazily, ie it doesn't look for the next element until it has to. I *believe* this is the real underlying reason why a[3] gives 2 instead of 3, but I couldn't totally nail down a concrete answer to that, and it's also possible that it's using memory addresses from the original list behind the scenes, which would produce the same result.
5th May 2023, 8:29 AM
Orin Cook
Orin Cook - avatar
0
Dadaxon Xudayberganov 🇺🇿🇺🇿🇺🇿 Why are you iterating on a list using an item from the same list as loop variable?
5th May 2023, 9:03 AM
Emerson Prado
Emerson Prado - avatar
0
Emerson Prado It is not my example. It is from Solo learn examples
5th May 2023, 9:11 AM
Dadaxon Xudayberganov 👑 🇺🇿🇺🇿
Dadaxon Xudayberganov 👑 🇺🇿🇺🇿 - avatar
0
Thanks everyone
5th May 2023, 9:13 AM
Dadaxon Xudayberganov 👑 🇺🇿🇺🇿
Dadaxon Xudayberganov 👑 🇺🇿🇺🇿 - avatar
0
Orin Cook i didnt say thats not valid i just say that dosent print out 3 3 3 3 😉
5th May 2023, 12:52 PM
S3R43o3
S3R43o3 - avatar
0
That sounds good until you dig into how iter() is implemented under the hood. When you do "X in Y," it doesn't actually use Y itself but an explicit iterable-type object copied from Y. Still, if you're 100% sure it's not lazy, that tells us that it's copying Y by reference rather than value, which is an interesting thing to know.
5th May 2023, 5:14 PM
Orin Cook
Orin Cook - avatar
0
that doesn't actually demonstrate anything because your iterator is constructed from the iterable range(), not from the list. ps range() is explicitly implemented lazily, so double the non-demonstration
5th May 2023, 6:05 PM
Orin Cook
Orin Cook - avatar
0
ok, so if I did this right I think this actually proves that iter() *IS* lazy: https://code.sololearn.com/cmecKbEa7uh4/?ref=app
5th May 2023, 6:32 PM
Orin Cook
Orin Cook - avatar
0
Mirielle that is incorrect, go look up iter(), __iter__, and __next__. Creating a new iterable object is exactly how it's implemented under the hood.
6th May 2023, 3:11 PM
Orin Cook
Orin Cook - avatar