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=106&thread=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