4 ms·
> My big regret with Python 3.0 is that the scoping rules in list expressions changed to prohibit modification of variables in surrounding scope. This degraded
by hellofunk 8y ago
> My big regret with Python 3.0 is that the scoping rules in list expressions changed to prohibit modification of variables in surrounding scope. This degraded the utility of list expressions. The work around is so long-winded.
Can you elaborate? I'm not sure what this is referring to.
- duckerude 8y agoIn Python 2, "[x for x in range(10)]; print(x)" prints 9. x is available outside the list comprehension. In Python 3, it raises a NameError, because the x in "print(x)" is not defined. It's contained in the list comprehension. But I don't know a good use of the Python 2 behavior.
- eesmith 8y agoIn Python 2.x the loop variable is part of the containing scope: >>> a Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name 'a' is not defined >>> [a*2 for a in (1,2,3)] [2, 4, 6] >>> a 3 In Python 3.x, it is not: >>> a Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name 'a' is not defined >>> [a*2 for a in (1,2,3)] [2, 4, 6] >>> a Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name 'a' is not defined It is sometimes useful to know why something failed. The following Python 2 code will not work in Python 3: >>> import math >>> try: ... values = [math.sqrt(x) for x in (1, 2, -3, 4)] ... except ValueError: ... print("cannot compute sqrt(%r)" % x) ... cannot compute sqrt(-3) I have mostly found this feature of Python 2 to be useful on the interactive shell, when trying to diagnose what caused an error in my list comprehension. Eg. >>> with open("tmp.dat") as input_file: ... fields = [line.split()[3] for line in input_file] ... Traceback (most recent call last): File "<stdin>", line 2, in <module> IndexError: list index out of range >>> line 'one two three\n' Oops, there are only 3 columns, not 4.
- w-m 8y agoWhen you use iPython you can just drop into the context of the error with %debug after it occurred, and then print the line there. No need for the bleeding scope on the language level.
- aidos 8y agoI’m the same, I would never use that side effect in production code but I do miss having it in ipython though my use is slight different. I often did: >>> [d for d in drawings] >>> [d.<tab> ...] Because I’m lazy and I want the autocomplete to be there for me. It’s actually the only thing I miss from python 2 and I will admit that a couple of times the sideffects have caught me out in production code so I’m happy with the change. It’s worth noting that the latest python pep is going to give you a way to assign the variables in the outer scope again: https://www.python.org/dev/peps/pep-0572/#simplifying-list-comprehensions https://www.python.org/dev/peps/pep-0572/#simplifying-list-c...
- deleted 8y ago[deleted]
- kozlovsky 8y agoIn Python 3.8 you will be able to use assignment expressions: [a := x*2 for x in (1, 2, 3)] See PEP 572 -- Assignment Expressions: https://www.python.org/dev/peps/pep-0572/ https://www.python.org/dev/peps/pep-0572/