On 2 May 2005 16:14:57 -0700, [EMAIL PROTECTED] (Brian Roberts) wrote: >I'm using using generators and iterators more and more intead of >passing lists around, and prefer them. However, I'm not clear on the >best way to detect an empty generator (one that will return no items) >when some sort of special case handling is required. > >Typical code for handling an empty list: > if somelist: > for x in somelist: > something(x) > else: > empty_list_special_case > >But this doesn't work with iterators -- a generator is "true" >regardless of whether its going to return any items. (I understand >why). > >The closest equivalent I know of is: > n = 0 > for n, x in enumerate(somegenerator()): > something(x) > if n == 0: > empty_list_special_case > >Which seems rather awkward -- doesn't read as easily for me, and >introduces another variable. And, if I understood the intent, doesn't work ;-)
>>> n = 0 >>> for n, x in enumerate(c for c in 'a'): ... print 'something', x ... something a >>> if n == 0: ... print 'empty list special case ??' ... empty list special case ?? You could have used n = -1 as a sentinel that enumerate would not set, but using a guaranteed-unique sentinel, you don't need enumerate, e.g., >>> x = sentinel = object() >>> for x in (c for c in 'a'): ... print 'something', x ... something a >>> if x is sentinel: ... print 'empty list special case ??' ... (nothing printed there) and for the actually empty sequence >>> x = sentinel = object() >>> for x in (c for c in ''): ... print 'something', x ... >>> if x is sentinel: ... print 'empty list special case ??' ... empty list special case ?? > >Q1: Is there a better or alternate way to handle this? >Q2: Is there a way that handles both lists and generators, so I don't >have to worry about which one I've got? > UIAM this should work for any iterable. You don't have to manufacture a locally bound sentinel as above. You could pick anything to preset the for-target that you know is not going to be produced by the iterable, though you might need to use '==' instead of 'is' depending on your choice. But e.g., I don't think I'd write x = Exception # weird sentinel choice for x in mystring: print x, ord(x) if x is Exception: print 'null sequence' None probably works well a lot of the time, but not always. Similarly ''. Seems like a builtin sentinel binding like sentinel = object() might be handy to standardize usage. Regards, Bengt Richter -- http://mail.python.org/mailman/listinfo/python-list