On Thu, 22 Jan 2009 10:11:37 -0800 (PST) Raymond Hettinger <pyt...@rcn.com> wrote:
> The collections module in Python 2.7 and Python 3.1 has gotten a new > Counter class that works like bags and multisets in other languages. I like that! Now that we have a multiset or Counter I think a redefinition of itertools.permutations is in order. For example something like this: def genperm(D, R = []): #generate the permutations of a multiset if not max(D.values()): yield tuple(R) else: for k,v in sorted(D.items()): if v: D[k] -= 1 for g in genperm(D,R+[k]): yield g D[k] += 1 def perm(seq): D = {} for x in seq: D[x] = D.get(x,0)+1 for X in genperm(D): yield X def test(): for i,x in enumerate(perm('aabbcc')): print i,x print len(set(perm('aabbcc'))) if __name__ == '__main__': test() The dictionary I'm using here could be seamlessly replaced by your Counter class. By the way, I like your itertools recipes a lot, but I miss something that repeats elements n times, an xcycle or ncycle or whatever, like I used in this (older code, sorry for the name overlap): def repeat(x,n = 0): i = 0 while i < n : yield x i += 1 def xcycle(seq,n): while 1: for x in seq: for y in repeat(x,n): yield y def counter(symbols,width): base = len(symbols) R = [] k = width while k: k -= 1 R.append(xcycle(symbols,base**k)) nc = base**width while nc: yield list(x.next() for x in R) nc -=1 def test(): symbols = '01' width = 4 for state in counter(symbols,width): print state if __name__=='__main__': test() I think such a thing could be handy for generating more kinds of periodic sequences. By the way, itertools is starting to feel like it's becoming some sort of alternate programming design all by itself. I wonder when it is going to break loose from python! I like that way of thinking a lot, thanks. P. -- http://mail.python.org/mailman/listinfo/python-list