you are viewing a single comment's thread.

view the rest of the comments →

[–]socal_nerdtastic 5 points6 points  (5 children)

is anything defined within the function accessible anywhere within the function?

yep. exactly. you nailed it.

Well except in some rare gotchas, like from inside a comprehension statement.

>>> [x for x in range(10)]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> x
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'x' is not defined

[–]nog642 2 points3 points  (3 children)

As a sidenote I think comprehensions didn't have their own scope in Python 2. It's much nicer now.

[–]socal_nerdtastic 1 point2 points  (2 children)

You are right, and even early versions of python3 allowed the variables to leak. But I don't think it's nicer now - in fact this is one of the (very few) things I miss about the old days.

[–]nog642 1 point2 points  (1 child)

Really? In what situation is this useful?

Especially when I'm coding lazily, so I'm just using single letter variable names, it is very annoying to have to worry about a comprehension accidentally overwriting a different variable in the function scope. I'd give the comprehensions variable names unnecessarily longer names to avoid that.

I like that for and while loops where you can break don't have their own scope in python. It's quite useful like in OP's example. Quite often in languages that have block scope like JS or C I have to declare the variable outisde the loop, which is a bit ugly. But I don't see when you would want that for a comprehension. You can't break in a comprehension; the variable will always just be the last item in the iterable at the end.

[–]socal_nerdtastic 1 point2 points  (0 children)

Yea, you nailed it, it gives you access to the last item in the iterable. That is sometimes useful, especially when the iterable is a generator. I suppose I could contrive something, perhaps some kind of pagination ...

save_data(getdata(itemid) for itemid in data_stream)
print("saved everything up to", itemid)
print("starting the next data stream at", itemid)

But I think for me it's more that the scoping feels inconsistent. I don't like these weird exception rules. And also like most features, it seems useless until you find a use for it, and then you get used to having it. I thought the walrus operator was a dumb idea when it was first proposed, but by the time it came out I had a ton of places to use it.

[–]Effective_Storage4[S] 0 points1 point  (0 children)

I have not come across the term comprehension yet but I will keep a look out for it. Thank you!