Velocity Reviews > a few extensions for the itertools

# a few extensions for the itertools

Mathias Panzenboeck
Guest
Posts: n/a

 11-19-2006
I wrote a few functions which IMHO are missing in python(s itertools).

http://sourceforge.net/project/showf...kage_id=212104

A short description to all the functions:

icmp(iterable1, iterable2) -> integer
Return negative if iterable1 < iterable2,
zero if iterable1 == iterable1,
positive if iterable1 > iterable1.

isum(iterable, start=0) -> value
Returns the sum of the elements of a iterable
plus the value of parameter 'start'. When the
iterable is empty, returns start.

iproduct(iterable, start=0) -> value
Returns the product of the elements of a iterable
times the value of parameter 'start'. When the
iterable is empty, returns start.

forall(predicate, iterable, default=True) -> bool
Returns True, when for all elements x in iterable
predicate(x) is True. When the iterable is empty,
returns default.

forany(predicate, iterable, default=False) -> bool
Returns True, when for any element x in iterable
predicate(x) is True. When the iterable is empty,
returns default.

take(n,iterable) -> iterator
returns a iterator over the first n
elements of the iterator

drop(n,iterable) -> iterable
drops the first n elemetns of iterable and
return a iterator over the rest

example:

output:
[]
[1]
[1, 2]
[1, 2, 3]
[1, 2, 3, 4]
[1, 2, 3, 4, 5]
[1, 2, 3, 4, 5, 6]
[1, 2, 3, 4, 5, 6, 7]
[1, 2, 3, 4, 5, 6, 7, 8]
[1, 2, 3, 4, 5, 6, 7, 8, 9]

tails(iterable) -> iterator over all tails
example:
for tail in tails([1,2,3,4,5,6,7,8,9]):
print tail

output:
[1, 2, 3, 4, 5, 6, 7, 8, 9]
[2, 3, 4, 5, 6, 7, 8, 9]
[3, 4, 5, 6, 7, 8, 9]
[4, 5, 6, 7, 8, 9]
[5, 6, 7, 8, 9]
[6, 7, 8, 9]
[7, 8, 9]
[8, 9]
[9]
[]

fcain(funct,*functs) -> function(...,***)
fcain(f1,f2,...,fn)(*args,*kwargs) equals f1(f2(...fn(*args,*kwargs)))

Paul McGuire
Guest
Posts: n/a

 11-19-2006
"Mathias Panzenboeck" <(E-Mail Removed)> wrote in message
news:4560bfb0\$0\$10578\$(E-Mail Removed) ...
>I wrote a few functions which IMHO are missing in python(s itertools).
>
> http://sourceforge.net/project/showf...kage_id=212104
>
> A short description to all the functions:
>

Just a couple of questions:

> iproduct(iterable, start=0) -> value
> Returns the product of the elements of a iterable
> times the value of parameter 'start'. When the
> iterable is empty, returns start.
>

Wouldn't 1 be a better default value for start?

> forall(predicate, iterable, default=True) -> bool
> Returns True, when for all elements x in iterable
> predicate(x) is True. When the iterable is empty,
> returns default.
>
>
> forany(predicate, iterable, default=False) -> bool
> Returns True, when for any element x in iterable
> predicate(x) is True. When the iterable is empty,
> returns default.
>

How are these different from all and any in Python 2.5?

-- Paul

Steven D'Aprano
Guest
Posts: n/a

 11-19-2006
On Sun, 19 Nov 2006 21:35:24 +0100, Mathias Panzenboeck wrote:

> I wrote a few functions which IMHO are missing in python(s itertools).
>
> http://sourceforge.net/project/showf...kage_id=212104
>
> A short description to all the functions:
>
> icmp(iterable1, iterable2) -> integer
> Return negative if iterable1 < iterable2,
> zero if iterable1 == iterable1,
> positive if iterable1 > iterable1.

What does it mean for an iterable to be less than another iterable? That
it has fewer items? How do these two iterables compare?

iter([1, 2, None, "foo", 3+2j])

def ones():
while 1:
yield 1

Which is smaller?

> isum(iterable, start=0) -> value
> Returns the sum of the elements of a iterable
> plus the value of parameter 'start'. When the
> iterable is empty, returns start.

You mean just like the built-in sum()?

>>> sum(xrange(12), 1000)

1066

> iproduct(iterable, start=0) -> value
> Returns the product of the elements of a iterable
> times the value of parameter 'start'. When the
> iterable is empty, returns start.

If I recall, product() was requested about the same time that sum() was
introduced, and Guido rejected it as a built-in because it was really only
useful for calculating geometric means, and it is easy to do if you need
it:

def product(it, start=1):
# default value of 1 is more sensible than 0
# 1 is the multiplicative identity
p = start
for x in it:
p *= x
return p

> forall(predicate, iterable, default=True) -> bool
> Returns True, when for all elements x in iterable
> predicate(x) is True. When the iterable is empty,
> returns default.
>
>
> forany(predicate, iterable, default=False) -> bool
> Returns True, when for any element x in iterable
> predicate(x) is True. When the iterable is empty,
> returns default.

I vaguely recall plans for all() and any() builtins -- perhaps for Python
2.5?

> take(n,iterable) -> iterator
> returns a iterator over the first n
> elements of the iterator

Just like itertools.islice(iterable, n).

>>> list(itertools.islice(xrange(10), 5))

[0, 1, 2, 3, 4]

> drop(n,iterable) -> iterable
> drops the first n elemetns of iterable and
> return a iterator over the rest

Just like itertools.islice(iterable, n, None)

>>> list(itertools.islice(xrange(20), 15, None))

[15, 16, 17, 18, 19]

(Aside: I think islice would be so much cleaner if it took keyword
arguments.)

> tails(iterable) -> iterator over all tails

What would you use these for?

> fcain(funct,*functs) -> function(...,***)
> fcain(f1,f2,...,fn)(*args,*kwargs) equals f1(f2(...fn(*args,*kwargs)))

The usual term for this is function composition.

--
Steven.

Carl Banks
Guest
Posts: n/a

 11-20-2006

Paul McGuire wrote:
> "Mathias Panzenboeck" <(E-Mail Removed)> wrote in message
> news:4560bfb0\$0\$10578\$(E-Mail Removed) ...
> >I wrote a few functions which IMHO are missing in python(s itertools).
> >
> > http://sourceforge.net/project/showf...kage_id=212104
> >
> > A short description to all the functions:
> >

> Just a couple of questions:
>
> > iproduct(iterable, start=0) -> value
> > Returns the product of the elements of a iterable
> > times the value of parameter 'start'. When the
> > iterable is empty, returns start.
> >

> Wouldn't 1 be a better default value for start?

I concur; start should default to 1.

> > forall(predicate, iterable, default=True) -> bool
> > Returns True, when for all elements x in iterable
> > predicate(x) is True. When the iterable is empty,
> > returns default.
> >
> > forany(predicate, iterable, default=False) -> bool
> > Returns True, when for any element x in iterable
> > predicate(x) is True. When the iterable is empty,
> > returns default.
> >

> How are these different from all and any in Python 2.5?

1. These functions apply a predicate to the items. It's simple enough
to do with any/all and a genexp, but by the same argument, it's simple
enough to do imap and ifilter with a plain genexp.
2. They have default values. Default values for any and all don't make
sense, and I don't think they make sense here, either. All of nothing
is always True; any of nothing is always False.

Carl Banks

Gabriel Genellina
Guest
Posts: n/a

 11-20-2006
At Sunday 19/11/2006 17:35, Mathias Panzenboeck wrote:

>I wrote a few functions which IMHO are missing in python(s itertools).
>
>http://sourceforge.net/project/showf...kage_id=212104
>
>isum(iterable, start=0) -> value
> Returns the sum of the elements of a iterable
> plus the value of parameter 'start'. When the
> iterable is empty, returns start.

Isn't the same as the builtin sum?

>iproduct(iterable, start=0) -> value

As others said, start should be 1

>fcain(funct,*functs) -> function(...,***)
> fcain(f1,f2,...,fn)(*args,*kwargs) equals
> f1(f2(...fn(*args,*kwargs)))

I don't understand it, nor even the signature. Perhaps it tries to be
"fchain", function composition? But what has it to do with iterables?

--
Gabriel Genellina
Softlab SRL

__________________________________________________
Correo Yahoo!
Espacio para todos tus mensajes, antivirus y antispam ˇgratis!
ˇAbrí tu cuenta ya! - http://correo.yahoo.com.ar

George Sakkis
Guest
Posts: n/a

 11-20-2006
Steven D'Aprano wrote:

> > A short description to all the functions:
> >
> > icmp(iterable1, iterable2) -> integer
> > Return negative if iterable1 < iterable2,
> > zero if iterable1 == iterable1,
> > positive if iterable1 > iterable1.

>
>
> What does it mean for an iterable to be less than another iterable? That
> it has fewer items? How do these two iterables compare?
>
> iter([1, 2, None, "foo", 3+2j])
>
> def ones():
> while 1:
> yield 1
>
> Which is smaller?

Haven't checked the specific implementation, but I would expect it to
behave like sequences of the same type, i.e. first compare the first
elements of the iterables; if they are equal compare the second
elements, and so on, until the first inequality or until the shorter
one ends. In your example, the second iterable is smaller. Needless to
say, you'd better not compare an infinite iterable with itself

> > drop(n,iterable) -> iterable
> > drops the first n elemetns of iterable and
> > return a iterator over the rest

>
> Just like itertools.islice(iterable, n, None)
>
> >>> list(itertools.islice(xrange(20), 15, None))

> [15, 16, 17, 18, 19]
>
> (Aside: I think islice would be so much cleaner if it took keyword
> arguments.)

How about slice notation ? I just posted in the Cookbook an OO wrapper
of itertools that, among other functions, uses slice notation for
islice and "+" for chain. Admittedly, my proposal in the py-3k list to
make iter() return itertools-enabled iterators was overwhelmingly shot
down, but I still like it anyway. FWIW, here's the Cookbook link:

http://aspn.activestate.com/ASPN/Coo.../Recipe/498272

George

Duncan Booth
Guest
Posts: n/a

 11-20-2006
Mathias Panzenboeck <(E-Mail Removed)> wrote:

> take(n,iterable) -> iterator
> returns a iterator over the first n
> elements of the iterator

Isn't this just the same as itertools.islice(iterable, n) ?

> drop(n,iterable) -> iterable
> drops the first n elemetns of iterable and
> return a iterator over the rest

and this looks to be the same as itertools.islice(iterable, n, None)

Can you give use cases for 'heads' and 'tails'? I'm curious why you would
want them.

Mathias Panzenboeck
Guest
Posts: n/a

 11-20-2006
Gabriel Genellina wrote:
> At Sunday 19/11/2006 17:35, Mathias Panzenboeck wrote:
>
>> I wrote a few functions which IMHO are missing in python(s itertools).
>>
>> http://sourceforge.net/project/showf...kage_id=212104
>>
>>
>> isum(iterable, start=0) -> value
>> Returns the sum of the elements of a iterable
>> plus the value of parameter 'start'. When the
>> iterable is empty, returns start.

>
> Isn't the same as the builtin sum?
>

No, because the builtin sum want's a list. This can also handle any kind of iterable, so this would
work:

isum(i**2 for i in xrange(100))

sum would need firs the whole list to be generated:

sum([i**2 for i in xrange(100)])

>> iproduct(iterable, start=0) -> value

>
> As others said, start should be 1
>

Indeed. Can't believe I made that mistake... the mistake is only in the documentation.

>> fcain(funct,*functs) -> function(...,***)
>> fcain(f1,f2,...,fn)(*args,*kwargs) equals
>> f1(f2(...fn(*args,*kwargs)))

>
> I don't understand it, nor even the signature. Perhaps it tries to be
> "fchain", function composition? But what has it to do with iterables?
>

Ups, missed out the 'h'. (Also only in the documentation.)

It's like the . operator in haskell:

fchain(f,g,h) is the same like lambda *args,**kwargs: f(g(h(*args,**kwargs)))

Mathias Panzenboeck
Guest
Posts: n/a

 11-20-2006
Duncan Booth wrote:
> Mathias Panzenboeck <(E-Mail Removed)> wrote:
>
>> take(n,iterable) -> iterator
>> returns a iterator over the first n
>> elements of the iterator

>
> Isn't this just the same as itertools.islice(iterable, n) ?
>

ok, that's true.

>> drop(n,iterable) -> iterable
>> drops the first n elemetns of iterable and
>> return a iterator over the rest

>
> and this looks to be the same as itertools.islice(iterable, n, None)
>

same here.

> Can you give use cases for 'heads' and 'tails'? I'm curious why you would
> want them.

I use them in haskell all the time. But in haskell the lists are all "generators".

In haskell you would implement naive string-search like this:

import List
findIndex (isPrefixOf "bla") (tails "dfvbdbblaesre")

Mathias Panzenboeck
Guest
Posts: n/a

 11-20-2006
Steven D'Aprano wrote:
> On Sun, 19 Nov 2006 21:35:24 +0100, Mathias Panzenboeck wrote:
>
>> I wrote a few functions which IMHO are missing in python(s itertools).
>>
>> http://sourceforge.net/project/showf...kage_id=212104
>>
>> A short description to all the functions:
>>
>> icmp(iterable1, iterable2) -> integer
>> Return negative if iterable1 < iterable2,
>> zero if iterable1 == iterable1,
>> positive if iterable1 > iterable1.

>
>
> What does it mean for an iterable to be less than another iterable? That
> it has fewer items? How do these two iterables compare?
>
> iter([1, 2, None, "foo", 3+2j])
>
> def ones():
> while 1:
> yield 1
>
> Which is smaller?
>
>

it's like cmp on lists, but on iterables.

[1,2,3] < [1,2,4]
[1,2,3] < [1,2,3,0]
....

>
>> isum(iterable, start=0) -> value
>> Returns the sum of the elements of a iterable
>> plus the value of parameter 'start'. When the
>> iterable is empty, returns start.

>
>
> You mean just like the built-in sum()?
>

No, because the builtin sum can't handle iterables other than lists. Or dose it? Hmm, maby it dose
since any new version and I didn't mention it.

>>>> sum(xrange(12), 1000)

> 1066
>
>
>> iproduct(iterable, start=0) -> value
>> Returns the product of the elements of a iterable
>> times the value of parameter 'start'. When the
>> iterable is empty, returns start.

>
> If I recall, product() was requested about the same time that sum() was
> introduced, and Guido rejected it as a built-in because it was really only
> useful for calculating geometric means, and it is easy to do if you need
> it:
>
> def product(it, start=1):
> # default value of 1 is more sensible than 0
> # 1 is the multiplicative identity
> p = start
> for x in it:
> p *= x
> return p
>
>
>> forall(predicate, iterable, default=True) -> bool
>> Returns True, when for all elements x in iterable
>> predicate(x) is True. When the iterable is empty,
>> returns default.
>>
>>
>> forany(predicate, iterable, default=False) -> bool
>> Returns True, when for any element x in iterable
>> predicate(x) is True. When the iterable is empty,
>> returns default.

>
>
> I vaguely recall plans for all() and any() builtins -- perhaps for Python
> 2.5?
>

all() and any() don't get predicate functions as arguments.

>
>> take(n,iterable) -> iterator
>> returns a iterator over the first n
>> elements of the iterator

>
> Just like itertools.islice(iterable, n).
>
>>>> list(itertools.islice(xrange(10), 5))

> [0, 1, 2, 3, 4]
>

ok, ok, ok. I have overseen that.

>
>> drop(n,iterable) -> iterable
>> drops the first n elemetns of iterable and
>> return a iterator over the rest

>
> Just like itertools.islice(iterable, n, None)
>
>>>> list(itertools.islice(xrange(20), 15, None))

> [15, 16, 17, 18, 19]
>
> (Aside: I think islice would be so much cleaner if it took keyword
> arguments.)
>
>
>
>> tails(iterable) -> iterator over all tails

>
> What would you use these for?
>
>
>> fcain(funct,*functs) -> function(...,***)
>> fcain(f1,f2,...,fn)(*args,*kwargs) equals f1(f2(...fn(*args,*kwargs)))

>
>
> The usual term for this is function composition.
>
>