List comprehesion

Question:

For input values, i. e. x, y, z, n, I wanted to print all combinations as list comprehesion, where 0<=i<=x, 0<=j<=y, 0<=k<=z, where i+j+k != n.

How to do this? I was thinking about using itertools.permutations() but I don’t know how. How to input these x, y, z, n in appropriate format?

Asked By: Malum Phobos

||

Answers:

[(i,j,k) for i in range(x+1) for j in range(y+1) for k in range(z+1) if i+j+k!=n]

Some timeit consideration. With x=10, y=8, z=6, n=10

  • This method (let’s call it "triple for method") : 3.27 (sec for 50000 runs on my machine)
  • Barmar’s method ("product/sum method) : 3.56

So, we all loose, since the best method (so far) is a compromise between those 2:

# Fastest so far
[(i,j,k) for i,j,k in itertools.product(range(x+1),range(y+1),range(z+1)) if i+j+k!=n]

So, the main idea is Barmar’s one (using itertools.product). What makes their solution slower, is just the call to "sum", I think. Not that it is expansive, but compared to i+j+k…

So this 3rd solution avoid the triple for (well, not really. under the hood ".product" also have this triple for. But the difference is that my triple for is in interpreted python, while itertools.product is probably in compiled C code), and also avoid the call to sum. To the cost of handling 3 variables, but apparently it worth it. Timeit:

  • itertools/i+j+k method: 2.94

Generally speaking, for strictly identical task, one should favor itertools, because it is faster than real python for loops (well, compound list are not really for loops neither. But, still).
In this case, since computation is very fast anyway, a usually negligible difference (sum vs +) was sufficient to reverse the ranking. But we can get rid of it

Answered By: chrslg

Using itertools.product to get the cartesian product of all the ranges:

[triple for triple in itertools.product(range(x+1), range(y+1), range(z+1)) if sum(triple) != n]
Answered By: Barmar
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.