[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Please improve these comprehensions (was meaning of [ ])

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 []
        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