Path: csiph.com!newsfeed.hal-mli.net!feeder3.hal-mli.net!newsfeed.hal-mli.net!feeder1.hal-mli.net!newsfeed.xs4all.nl!newsfeed5.news.xs4all.nl!xs4all!post.news.xs4all.nl!not-for-mail Return-Path: X-Original-To: python-list@python.org Delivered-To: python-list@mail.python.org X-Spam-Status: OK 0.003 X-Spam-Evidence: '*H*': 0.99; '*S*': 0.00; 'python.': 0.02; 'else:': 0.03; 'skip:[ 20': 0.03; 'prefix': 0.07; 'defined,': 0.09; 'ignoring': 0.09; 'to:addr:comp.lang.python': 0.09; 'cc:addr :python-list': 0.10; 'def': 0.10; 'properly': 0.15; 'skip:f 30': 0.15; '10x': 0.16; 'itertools': 0.16; 'runs.': 0.16; 'set()': 0.16; 'true:': 0.16; 'written.': 0.16; 'wrote:': 0.17; 'yield': 0.17; 'skip:p 30': 0.20; 'import': 0.21; 'combination': 0.22; "i've": 0.23; 'second': 0.24; 'cc:2**1': 0.24; 'least': 0.25; 'cc:addr:python.org': 0.25; 'header:In-Reply-To:1': 0.25; 'header :User-Agent:1': 0.26; 'cc:addr:gmail.com': 0.27; 'right.': 0.27; 'convention': 0.27; 'set.': 0.27; 'then.': 0.27; 'skip:_ 10': 0.29; 'probably': 0.29; 'class': 0.29; 'thursday,': 0.30; 'implement': 0.32; 'subject:lists': 0.32; 'could': 0.32; 'crazy': 0.33; 'doubt': 0.33; 'problem': 0.33; 'code:': 0.33; 'hi,': 0.33; 'version': 0.34; 'received:google.com': 0.34; 'self': 0.34; 'done': 0.34; 'thanks': 0.34; 'faster': 0.35; 'from:addr:googlemail.com': 0.35; 'lists.': 0.35; 'received:209.85': 0.35; 'explain': 0.36; 'but': 0.36; 'possible': 0.37; 'october': 0.37; 'optimization': 0.37; 'being': 0.37; 'quite': 0.37; 'received:209': 0.37; 'subject:: ': 0.38; 'short': 0.39; 'your': 0.60; 'most': 0.61; 'you.': 0.61; 'first': 0.61; 'chance': 0.61; 'solve': 0.62; 'helps': 0.63; 'more': 0.63; 'within': 0.64; 'here': 0.65; 'life': 0.66; 'obvious': 0.71; 'interest.': 0.78; 'fast,': 0.84; 'yours.': 0.93 Newsgroups: comp.lang.python Date: Thu, 4 Oct 2012 12:20:00 -0700 (PDT) In-Reply-To: Complaints-To: groups-abuse@google.com Injection-Info: glegroupsg2000goo.googlegroups.com; posting-host=123.192.32.215; posting-account=5JdMBQoAAABHnS4mjpqEzxnmWtgiiVNw References: <506C4B23.6020809@gmail.com> User-Agent: G2/1.0 X-Google-Web-Client: true X-Google-IP: 123.192.32.215 MIME-Version: 1.0 Subject: Re: Combinations of lists From: 88888 Dihedral To: comp.lang.python@googlegroups.com Content-Type: text/plain; charset=ISO-8859-1 Cc: Python X-BeenThere: python-list@python.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: General discussion list for the Python programming language List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Message-ID: Lines: 169 NNTP-Posting-Host: 2001:888:2000:d::a6 X-Trace: 1349378409 news.xs4all.nl 6987 [2001:888:2000:d::a6]:33016 X-Complaints-To: abuse@xs4all.nl Xref: csiph.com comp.lang.python:30743 On Thursday, October 4, 2012 11:12:41 PM UTC+8, Steen Lysgaard wrote: > 2012/10/4 Joshua Landau : > > > On 3 October 2012 21:15, Steen Lysgaard wrote: > > >> > > >> Hi, > > >> > > >> thanks for your interest. Sorry for not being completely clear, yes > > >> the length of m will always be half of the length of h. > > > > > > > > > (Please don't top post) > > > > > > I have a solution to this, then. > > > It's not short or fast, but it's a lot faster than yours. > > > > > > But first let me explain the most obvious optimization to your version of > > > the code: > > > > > >> combs = set() > > >> > > >> > > >> for a in permutations(range(len(h)),len(h)): > > >> comb = [] > > >> for i in range(len(h)): > > >> comb.append(c[i][a[i]]) > > >> comb.sort() > > >> > > >> frzn = tuple(comb) > > >> if frzn not in combs: > > >> combs.add(frzn) > > > > > > > > > What I have done here is make your "combs" a set. This helps because you > > > are searching inside it and that is an O(N) operation... for lists. > > > A set can do the same in O(1). Simplez. > > > > > > first = list("AABBCCDDEE") > > > second = list("abcde") > > > import itertools > > > # > > > # Generator, so ignoring case convention > > > class force_unique_combinations: > > > def __init__(self, lst, n): > > > self.cache = set() > > > self.internal_iter = itertools.combinations(lst, n) > > > def __iter__(self): > > > return self > > > def __next__(self): > > > while True: > > > nxt = next(self.internal_iter) > > > if not nxt in self.cache: > > > self.cache.add(nxt) > > > return nxt > > > def combine(first, second): > > > sletter = second[0] > > > first_combinations = force_unique_combinations(first, 2) > > > if len(second) == 1: > > > for combination in first_combinations: > > > yield [sletter+combination[0], sletter+combination[1]] > > > else: > > > for combination in first_combinations: > > > first_ = first[:] > > > first_.remove(combination[0]) > > > first_.remove(combination[1]) > > > prefix = [sletter+combination[0], sletter+combination[1]] > > > for inner in combine(first_, second[1:]): > > > yield prefix + inner > > > > > > > > > This is quite naive, because I don't know how to properly implement > > > force_unique_combinations, but it runs. I hope this is right. If you need > > > significantly more speed your best chance is probably Cython or C, although > > > I don't doubt 10x more speed may well be possible from within Python. > > > > > > > > > Also, 88888 Dihedral is a bot, or at least pretending like crazy to be one. > > > > Great, I've now got a solution much faster than what I could come up with. > > Thanks to the both of you. > > And a good spot on 88... I could not for my life understand what he > > (it) had written. > > > > /Steen If an unique order is defined, then it is trivial to solve this problem without any recursions.