Re: py3k printing generators -- not!

2009-06-06 Thread Carl Banks
On Jun 6, 5:28 am, samwyse samw...@gmail.com wrote:
 The one thing that's killing me in Python 3000 is that every time I
 try to print something, it seems like I get generator object
 genexpr at 0x01BAF508.  Googling only found one reference, a
 posting elsewhere by one Carl Johnson (aka 
 carlj7,http://www.artima.com/forums/flat.jsp?forum=106thread=211200#275387),
 which apparently was never answered.  Is anyone else finding this
 bothersome, or is it entirely due to my FP background?

 Always saying print(','.join(x)) gets tiresome in a hurry.  

What about print(list(x))

 I've
 thought about defining my own function prnt that wraps print and
 fixes generators, but that requires me to get their type, which
 despite the claims of help(type(x for x in range(0))) cannot be
 found in builtins.

Interestingly, the fact that it wasn't in builtins didn't stop you
from being able to pass the type to the help() function.  I wonder if
you can use the same trick to obtain the type for use in your prnt()
function.

(Failing that, you could use from types import GeneratorType.)

 How are other solving this?

In my experience, if you want a custom print function that prints
things the way you want, you have to write it yourself.  People's
expectations are too different.


Carl Banks
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: py3k printing generators -- not!

2009-06-06 Thread bearophileHUGS
samwyse:
 Always saying print(','.join(x)) gets tiresome in a hurry.  I've
 thought about defining my own function prnt that wraps print and
 fixes generators, but that requires me to get their type,

Why do you need to know their type?
Isn't something like this enough?

def pr(it):
txt = .join(map(str, it))
print(txt)

That little function can be improved in many ways.


 despite the claims of help(type(x for x in range(0)))
 cannot be found in builtins.

Python can yield mixed types (nearly never recommended):

def foo():
  yield 1
  yield hello
  yield 1.5

Bye,
bearophile
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: py3k printing generators -- not!

2009-06-06 Thread bearophileHUGS
Carl Banks:
 What about print(list(x))

Right, better than mine :-)

Bye,
bearophile
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: py3k printing generators -- not!

2009-06-06 Thread samwyse
On Jun 6, 7:58 am, Carl Banks pavlovevide...@gmail.com wrote:
 On Jun 6, 5:28 am, samwyse samw...@gmail.com wrote:

  Always saying print(','.join(x)) gets tiresome in a hurry.  

 What about print(list(x))

Yeah, I like that.  Or, to save some typing:
  prnt = lambda x: print(list(x))

 Interestingly, the fact that it wasn't in builtins didn't stop you
 from being able to pass the type to the help() function.  I wonder if
 you can use the same trick to obtain the type for use in your prnt()
 function.

Of course, but it would mean evaluating an expression every time I
defined my function.  That just seems unhygenic

 (Failing that, you could use from types import GeneratorType.)

Ah!  I should've thought of that.

 In my experience, if you want a custom print function that prints
 things the way you want, you have to write it yourself.  People's
 expectations are too different.

Well, that's why I rferenced the other article,
http://www.artima.com/forums/flat.jsp?forum=106thread=211200#275387),
to show that other people have the same expectations.  (In the
article, Carl Johnson correctly points out that the real problem is
that str() responds to generators differently than do the other
collection types.)
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: py3k printing generators -- not!

2009-06-06 Thread Steven D'Aprano
On Sat, 06 Jun 2009 05:28:30 -0700, samwyse wrote:

 The one thing that's killing me in Python 3000 

Python 3000 was vapourware. When the vapour condensed into liquid, it was 
renamed Python 3. Right now, the only vapourware is Python4000, which may 
or may not be created by Guido's heir some time in the 2020s.


 is that every time I try
 to print something, it seems like I get generator object genexpr at
 0x01BAF508.

Every time? Really? Even when you print an object which isn't a 
generator?


 Googling only found one reference, a posting elsewhere by
 one Carl Johnson (aka carlj7,
 http://www.artima.com/forums/flat.jsp?forum=106thread=211200#275387),
 which apparently was never answered.

Ignoring Carl's totally pointless mycond() function, he apparently 
wants type(iterable)(i for i in iterable) to give iterable:

 it = [1, 2]
 type(it)(i for i in it)
[1, 2]


But that can't work for arbitrary iterables:

 it = {1:2, 3:4}
 type(it)(i for i in it)
Traceback (most recent call last):
  File stdin, line 1, in module
TypeError: cannot convert dictionary update sequence element #0 to a 
sequence


Nor will it work for generator objects themselves:

 it = (1+x for x in range(5))
 type(it)(i for i in it)
Traceback (most recent call last):
  File stdin, line 1, in module
TypeError: cannot create 'generator' instances


So Carl's suggestion can't be applied universally, it can only hold for 
some iterables. It doesn't even hold for all sequences, with strings a 
conspicuous example. In fact, that's what Carl is complaining about:

 it = abc
 type(it)(i for i in it)
'generator object genexpr at 0xb7ce3d24'


He apparently would prefer str(i for i in abc) to return abc. 
However, you seem to prefer a,b,c instead. So what you would prefer, 
and what Carl would prefer, are different.

Either way though, there's a fatal flaw in the idea: printing an object 
shouldn't consume the object, but that's what you want. Unlike a list or 
a tuple, a generator is *code*, not a data type. It produces values when 
and as asked. So there's no way to peek inside a generator and see the 
values that it will produce, consequently, for str() to behave as you and 
Carl want, it has to run the generator to completion, performing an 
arbitrarily large amount of work (and perhaps, for non-terminating 
generators, never finishing!) before you can print it. And then, having 
printed it, the generator is now exhausted. Try to print it again, and 
you'll get the empty string.

Calling list() on a generator is different: it is *designed* to exhaust 
the generator. I'd be upset if print() and/or str() did the same thing.

I'd also be upset if generators looked like a string when they're not:

 x = (c.lower() for c in ABC)
 x
'abc'
 x.upper()  # x looks like a string, but it isn't
Traceback (most recent call last):
  File stdin, line 1, in module
AttributeError: 'generator' object has no attribute 'upper'



[...]
 I've
 thought about defining my own function prnt that wraps print and fixes
 generators, but that requires me to get their type, which despite the
 claims of help(type(x for x in range(0))) cannot be found in builtins.
  How are other solving this?

I'm not solving this, because I don't think this is a problem that 
needs solving. But if you want a custom print function, this should work:

def print(*values, **kwargs):
from builtins import print as pr
gen = type(x for x in [1,2])
values = [','.join(str(s) for s in obj) if type(obj) is gen 
 else obj for obj in values]
pr(*values, **kwargs)




-- 
Steven
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: py3k printing generators -- not!

2009-06-06 Thread Terry Reedy

samwyse wrote:

The one thing that's killing me in Python 3000


py3.0 or py3.1, but the 'problem' you complain about has nothing to do 
with those versions in particular.



is that every time I try to print something, it seems like I get generator 
object
genexpr at 0x01BAF508.


Nor does it have anything is particular to do with generator objects. 
Str(function/class/module/and-many-others) prints similarly. Since 
forever, str(ob) == ob.__str__() == type(ob).__str__(ob).  And what you 
see above is the default template filled in for a particular object.


Built-in concrete collections over-ride the default and return a string 
with their contents because they can do that without harm other than 
possibly producing a very long string.  When the collections are large, 
one might want a custom function that instead formats a string with a 
limited number of examples and the total count.


A 3.0 range object, a virtual collection, could do that too, but since 
there is a regular pattern, it prints a condensed representation. 
Aren't you glad, actually, that range(10) prints as range(0, 
10) instead of listing the billion numbers it produces when 
iterated, as you seem to be asking for?



 Googling only found one reference, a
posting elsewhere by one Carl Johnson (aka carlj7,
http://www.artima.com/forums/flat.jsp?forum=106thread=211200#275387),


A bogus complaint that the constructor for highly specialized class str 
acts differently from those of the general collection classes set, 
tuple, and list.  Str is actually not a collection class in the way that 
set, tuple, list, dict, and many others are.


Terry Jan Reedy

--
http://mail.python.org/mailman/listinfo/python-list