On Thu, 9 Nov 2005, it was written:

> [EMAIL PROTECTED] (Alex Martelli) writes:
>
>>> Is there a good reason to not define iter1+iter2 to be the same as
>>
>> If you mean for *ALL* built-in types, such as generators, lists, files,
>> dicts, etc, etc -- I'm not so sure.
>
> Hmm, there might also be __add__ operations on the objects, that would 
> have to take precedence over iterator addition.  Iterator addition 
> itself would have to be a special kludge like figuring out "<" from 
> __cmp__, etc.
>
> Yeah, I guess the idea doesn't work out that well.  Oh well.

How about if we had some sort of special sort of iterator which did the 
right thing when things were added to it? like an iterable version of The 
Blob:

class blob(object):
        def __init__(self, it=None):
                self.its = []
                if (it != None):
                        self.its.append(iter(it))
        def __iter__(self):
                return self
        def next(self):
                try:
                        return self.its[0].next()
                except StopIteration:
                        # current iterator has run out!
                        self.its.pop(0)
                        return self.next()
                except IndexError:
                        # no more iterators
                        raise StopIteration
        def __add__(self, it):
                self.its.append(iter(it))
                return self
        def __radd__(self, it):
                self.its.insert(0, iter(it))

Then we could do:

all_lines = blob(file1) + file2 + file3
candidate_primes = blob((2,)) + (1+2*i for i in itertools.count(1))

Which, although not quite as neat, isn't entirely awful.

Another option would be a new operator for chaining - let's use $, since 
that looks like the chain on the fouled anchor symbol used by navies etc:

http://www.diggerhistory.info/images/badges-asstd/female-rels-navy.jpg

Saying "a $ b" would be equivalent to "chain(a, b)", where chain (which 
could even be a builtin if you like) is defined:

def chain(a, b):
        if (hasattr(a, "__chain__")):
                return a.__chain__(b)
        elif (hasattr(b, "__rchain__")): # optional
                return b.__rchain__(a)
        else:
                return itertools.chain(a, b) # or equivalent

Whatever it is that itertools.chain or whatever returns would be modified 
to have a __chain__ method which behaved like blob.__add__ above. This 
then gets you:

all_lines = file1 $ file2 $ file3
candidate_primes = (2,) $ (1+2*i for i in itertools.count(1))

And we're halfway to looking like perl already! Perhaps a more pythonic 
thing would be to define a "then" operator:

all_lines = file1 then file2 then file3
candidate_primes = (2,) then (1+2*i for i in itertools.count(1))

That looks quite nice. The special method would be __then__, of course.

tom

-- 
if you can't beat them, build them
-- 
http://mail.python.org/mailman/listinfo/python-list

Reply via email to