Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

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...


Those 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 ?


Yeah, 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.


> 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.


This. Not all generators can be converted to a list in a timely manner, seeing as infinite generators are supported.


Neither 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]


You 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.


It'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)


You don't even have to do the assignment at the begging of your snippet. You could just refer to the builtin module explicitly.


Write it as a list comprehension instead; it has identical syntax except for using square brackets instead of parentheses, and returns a list.


A 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.


Consider a generator that yields results indefinitely, or even merely millions of results. Are you still sure you want those printed to the repl? :)


The 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?


You'll need some killer heurstics: https://en.wikipedia.org/wiki/Halting_Problem


Er, I sorta knew that I was describing the halting problem, and was wondering if someone would fail to realize my sarcasm...


Yeah, I see that "should be easy enough" at the end. My bad.


That is all programs in general, checking a specific program is totally within bounds.


That 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.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: