Search code examples
pythonlist-comprehension

List comprehesion


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?


Solution

  • [(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