new itertools functions in Python 2.6
Mensanator
mensanator at aol.com
Fri Jul 18 20:58:24 EDT 2008
On Jul 16, 5:05 am, Mark Dickinson <dicki... at gmail.com> wrote:
> On Jul 16, 7:20 am, Mensanator <mensana... at aol.com> wrote:
>
> > > > ## Combinations with replacement
> > > > ## -----------------------------
> > > > ## aaa aab aac aad aae abb abc abd abe acc acd ace
> > > > ## add ade aee bbb bbc bbd bbe bcc bcd bce bdd bde
> > > > ## bee ccc ccd cce cdd cde cee ddd dde dee eee
> > > > ##
> > > > ## actual words: 35 (m+n-1)!/(n!(m-1)!) words: 35
> >>> for x in combinations(range(7), 4):
> ... x = [-1] + list(x) + [7]
> ... print ''.join(c*(x[i+1]-x[i]-1) for i, c in enumerate('abcde'))
<snip printout>
>
> Generalization left as an exercise for the reader.
First part of exercise: figure out what's going on.
##[-1, 0, 1, 2, 3, 7] ['', '', '', '', 'eee'] eee
##[-1, 0, 1, 2, 4, 7] ['', '', '', 'd', 'ee'] dee
##[-1, 0, 1, 2, 5, 7] ['', '', '', 'dd', 'e'] dde
##[-1, 0, 1, 2, 6, 7] ['', '', '', 'ddd', ''] ddd
##[-1, 0, 1, 3, 4, 7] ['', '', 'c', '', 'ee'] cee
##[-1, 0, 1, 3, 5, 7] ['', '', 'c', 'd', 'e'] cde
##[-1, 0, 1, 3, 6, 7] ['', '', 'c', 'dd', ''] cdd
##[-1, 0, 1, 4, 5, 7] ['', '', 'cc', '', 'e'] cce
##[-1, 0, 1, 4, 6, 7] ['', '', 'cc', 'd', ''] ccd
##[-1, 0, 1, 5, 6, 7] ['', '', 'ccc', '', ''] ccc
## Damn, that's clever
## empty strings disappear when joined
Here's what I came with for a generalization.
s = 'abcde'
m = len(s)
n = 3
mn1 = m+n-1
m1 = m-1
p = [tuple(''.join(c*(q[i+1]-q[i]-1) for i, c in enumerate(s))) \
for q in [[t for t in chain.from_iterable(([-1],r,[mn1]))] \
for r in combinations(range(mn1), m1)]]
I used the tuple() to give output consistent with the itertools
functions.
Combinations with replacement
[26 letters 4 at a time]
version 2 (Mark Dickinson)
-------------------------------------------------------
actual words: 23751 (m+n-1)!/(n!(m-1)!) words: 23751
0.828000068665 seconds
Drat, that's not very impressive.
And here I thought using chain.from_iterable was a nice touch.
Not much better than my version.
p = [i for i in ifilter(lambda x:
list(x)==sorted(x),product(s,repeat=n))]
Combinations with replacement
[26 letters 4 at a time]
(using ifilter(product))
-------------------------------------------------------
actual words: 23751 (m+n-1)!/(n!(m-1)!) words: 23751
0.84299993515 seconds
Maybe all the time saved not iterating through the entire
Cartesian Product is lost to the overhead of all that list
and string manipulation. Makes me wish they had done this
function directly in itertools.
Even the full Cartesian Product is faster despite being
almost 20 times larger:
Permutations with replacement
[26 letters 4 at a time]
(using product)
-------------------------------------------------------
0.453000068665 seconds for 456976 words
Not to mention my goofy ooloop6 program (which certainly
isn't a replacement for itertools since it only works with
a single sorted iterable).
Combinations with replacement
[26 letters 4 at a time]
original nested for loop
-------------------------------------------------------
0.18700003624 seconds for 23751 words
Permutations with replacement
[26 letters 4 at a time]
original nested for loop
-------------------------------------------------------
0.344000101089 seconds for 456976 words
So, maybe there simply ISN'T a GOOD way to do Combinations
With Replacement.
Thanks anyway.
>
> Mark
More information about the Python-list
mailing list