6 ms·
The biggest thing that drives me nuts about py3 is just that its repl doesn't evaluate generators. I'm sure they had their reasons, but I use python as my go-to
by tsuraan 13y ago
The biggest thing that drives me nuts about py3 is just that its repl doesn't evaluate generators. I'm sure they had their reasons, but I use python as my go-to calculator, and when simple operations with maps/ranges give me a representation of a generator ("<map object at ...", whatever), then it's just less useful to me. I could be alone in that use case though...
- bluecalm 13y agoThose things return generators now to avoid wasting memory (you don't need to create possibly humongous list and keep it in memory during the iteration). If you want a list, just do list(your expression). If you forgot about it then do: list(_) as the very next thing. Like this: >>> map(lambda x: x*x, range(1,10)) <map object at 0x02DDDB90> >>> list(_) [1, 4, 9, 16, 25, 36, 49, 64, 81] Wtp ?
- tsuraan 13y agoYeah, it's definitely something that can be worked around, but it's something I don't have to get around in python2, so I keep using python2. Nothing truly major, just a sticky point.
- teddyh 13y agoWrite it as a list comprehension instead; it has identical syntax except for using square brackets instead of parentheses, and returns a list.
- dded 13y agoA list comprehension would work for GP, who wants a calculator. But others like to try out snippets of code in the REPL before using them in programs, and in that case you want the code to be the same. Would the following work? It's been a while since I've had Py3 installed, so I can't casually try it. In your PYTHONSTARTUP, place the following: _map = map def map(f, *args): return list(_map(f, *args)) So you get lists in interactive mode, but iterators in actual scripts.
- dragonwriter 13y ago> The biggest thing that drives me nuts about py3 is just that its repl doesn't evaluate generators. If by evaluate you mean "convert to a list", that's sensible, since a generator may or may not be safe to convert to a list. If you want a list, wrap the generator to a call to the list() builtin function, and, voila.
- deleted 13y ago[deleted]
- rectangletangle 13y agoThis. Not all generators can be converted to a list in a timely manner, seeing as infinite generators are supported.
- deleted 13y ago[deleted]
- zephjc 13y agoConsider a generator that yields results indefinitely, or even merely millions of results. Are you still sure you want those printed to the repl? :)
- gizmo686 13y agoThat is the approach that Haskell takes. If the repl responds to ^C by aborting whatever line it was evaluating then infinite results are little more than annoying, and you quickly learn to restrict what it prints to the first few elements (in python this would just involve appending [:n]). Ultimatly this is a question of which uses you want to optimize. Personally, I find Haskell's approach more useful as a calculator. A middle ground that I have not seen is automatically evaluating the first few elements and showing those as part of the <object> output.
- reuven 13y agoThe Python interactive shell could check the user's input: If it'll take infinitely long to run (e.g., an infinite generator), then it'll halt. If the code will eventually return, then it'll be run, displaying results to the user. Seems simple enough, no?
- hyperpape 13y agoYou'll need some killer heurstics: https://en.wikipedia.org/wiki/Halting_Problem https://en.wikipedia.org/wiki/Halting_Problem
- maxerickson 13y agoIt's really only a solution if the calculator usage is on a small number of computers, but you can just import * an override of the map function that behaves however you want. The override is easy: pymap=map def map(...)... (and maybe for calculator style usage you would name your list returning map and range m and r, which would also help with not confusing them with the usual behavior)
- rectangletangle 13y agoYou don't even have to do the assignment at the begging of your snippet. You could just refer to the builtin module explicitly.
- falcolas 13y agoNeither does Python2. $ python Python 2.7.5 (default, Aug 25 2013, 00:04:04) >>> xrange(10) xrange(10) >>> list(_) [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
- tsuraan 13y agoYou are definitely correct; it's really the combination of py3 using generators more frequently (which is a definite good thing) with the py3 repl not evaluating them that keeps me going back to py2 for my repl needs. A more fair comparison is with ghci, which expands thunks and runs IO actions when functions return them. As others have pointed out, this can be "dangerous" in the sense of flooding your console with crap (try typing [1..] in ghci; its' annoying, but not the end of the world either), but it's also really convenient when that's what you want. The python2 repl/functions do what I want, and the python3 repl/functions don't, or at least don't often enough that I keep going back to python2 for all my repl needs. Just a random chunk of anecdata, I guess.