Re: py3k printing generators -- not!
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!
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!
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!
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!
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!
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