On Wednesday, September 6, 2017 at 4:29:56 PM UTC+5:30, Gregory Ewing wrote: > Seems to me you're making life difficult for yourself (and > very inefficient) by insisting on doing the whole computation > with sets. If you want a set as a result, it's easy enough > to construct one from the list at the end.
Sure with programmer hat firmly on that is the sensible view. But there are equally legitimate other hats to consider: Learning combinatorics for example. And from that point of view Python (or Haskell or whatever) should be mostly irrelevant. Whereas what should be relevant is what SICP calls ‘procedural epistemology’: https://mitpress.mit.edu/sicp/front/node3.html | Underlying our approach to this subject is our conviction that "computer | science" is not a science and that its significance has little to do with | computers. The computer revolution is a revolution in the way we think and in | the way we express what we think. The essence of this change is the emergence | of what might best be called procedural epistemology the study of the | structure of knowledge from an imperative point of view, as opposed to the | more declarative point of view taken by classical mathematical subjects. | Mathematics provides a framework for dealing precisely with notions of "what | is." Computation provides a framework for dealing precisely with notions of | "how to." Coming to the details in this case, the important difference between permutations and combinations is not the numbers nPr and nCr but that a permutation is a list and a combination is a set. So this definition of permutations is fine (almost): def perms(l): if not l: return [[]] x, xs = l[0], l[1:] return [p[:i] + [x] + p[i:] for p in perms(xs) for i in range(0,len(l))] >>> perms([1,2,3]) [[1, 2, 3], [2, 1, 3], [2, 3, 1], [1, 3, 2], [3, 1, 2], [3, 2, 1]] Because the abstract idea of a permutation is a list (sequence) And the implementation here is faithful to that [The outer being a list is a mild annoyance... We can let it pass] However in this: 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) the [n[0]] + l is misguidingly overspecific, ie it suggests an order which has no relevance or connection to the problem. Note that *as a programmer* this may be fine From the pov of studying math, its wrong Now if you want to agree with Chris in saying that python is unsuitable for doing math, that's fine. [I am tending to agree myself] I posted it because I genuinely thought I had missed some obvious way of splitting a set into an (arbitrary) element and a rest without jumping through hoops. Evidently not -- https://mail.python.org/mailman/listinfo/python-list