On Tuesday, September 5, 2017 at 6:59:11 PM UTC+5:30, Ben Bacarisse wrote: > Rustom Mody writes: > > > On Tuesday, September 5, 2017 at 1:44:24 AM UTC+5:30, Ben Bacarisse wrote: > >> Rustom Mody writes: > >> > >> > Here is some code I (tried) to write in class the other day > >> > > >> > The basic problem is of generating combinations > >> <snip> > >> > Now thats neat as far as it goes but combinations are fundamentally sets > >> > not lists > >> > > >> > So I thought python would do a better job > >> > I tried translating it to python and sets but it turned out more > >> > annoying than > >> > helpful > >> > Can someone improve it?? > >> > > >> > The straightforward translation of the above > >> > Which is ok so far > >> > > >> > > >> > def c(n,r): > >> > if r == 0: > >> > return [[]] > >> > elif len(n) == 0: > >> > return [] > >> > else: > >> > return [[n[0]] + l for l in c(n[1:],r-1)] + c(n[1:],r) > >> > > >> > > >> > Now to go from returning list of lists to set of sets: > >> > >> def cs(n, r): > >> if r == 0: > >> return [set()] > >> elif len(n) == 0: > >> return [] > >> else: > >> return [set([n[0]]) | l for l in cs(n[1:], r-1)] + cs(n[1:], r) > >> > >> ? > >> > >> It's not so neat if you also want n to be a set rather than a list > >> because the set equivalents of n[0] and n[1:] are a but more complex but > >> it's not that bad: > >> > >> def css(n,r): > >> if r == 0: > >> return [set()] > >> elif len(n) == 0: > >> return [] > >> else: > >> rest = n.copy() > >> e = rest.pop() > >> return [set([e]) | l for l in css(rest, r-1)] + css(rest, r) > > > > Trying out your code Ben… > > > >>>> css({1,2,3,4}, 2) > > [set([1, 2]), set([1, 3]), set([1, 4]), set([2, 3]), set([2, 4]), set([3, > > 4])] > > > >>>> type(css({1,2,3,4}, 2)) > > <type 'list'> > > > > Whereas with the cs I earlier gave: > >>>> cs(frozenset([1,2,3,4]), 2) > > frozenset([frozenset([2, 4]), frozenset([3, 4]), frozenset([2, 3]), > > frozenset([1, 3]), frozenset([1, 2]), frozenset([1, 4])]) > > If you want a (frozen) sets of sets I'd just the code to > > def css(n, r): > if r == 0: > return frozenset({frozenset()}) > elif len(n) == 0: > return frozenset() > else: > rest = set(n) > e = rest.pop() > return frozenset([frozenset([e]) > | l for l in list(css(rest, r-1))]) | css(rest, r) > > >>> css(frozenset({1,2,3,4}), 2) > frozenset({frozenset({2, 4}), frozenset({3, 4}), frozenset({2, 3}), > frozenset({1, 3}), frozenset({1, 2}), frozenset({1, 4})}) > > The switch from lists (using +) and frozen sets using | is the most > obvious change, but if the top-level argument might itself be a > frozenset then the copy must be changed to a set constructor so that pop > will work.
Yes… Pop et al wont work with frozen sets Containment wont work with sets — what mathematicians call 'not closed' All of which amounts to this that python sets are not really pleasant for math-work [Just for context: A teacher may have more important things to teach than python If the niggles get overbearing the vehicle may not be worth it ] Besides I find the name pop ridiculous Stacks imply a stronger order usage-discipline than lists Sets are unordered compared to lists To use a name traditionally reserved for a stack op on sets is quite nonsensical -- https://mail.python.org/mailman/listinfo/python-list