0

I want to produce a i,j vector where every i is combined with every j, a simple version of the code would be this:

n = 5
m = 3

for i in range(n):
    for j in range(m):
        print str(i) + ',' + str(j)

Resulting:

0,0
0,1
0,2
1,0
1,1
1,2
2,0
2,1
2,2
3,0
3,1
3,2
4,0
4,1
4,2

However if n is 8e6 and m is 200 (like in my case) this loop nesting becomes very slow.

  • Is there a numpy procedure to produce this combination in a C-like speed?
  • Is there any other way?

Thanks in advance.

Vishnu Upadhyay
  • 5,043
  • 1
  • 13
  • 24
Santi Peñate-Vera
  • 1,053
  • 4
  • 33
  • 68
  • Where do you want this output to be redirected? To a file, pipe, std? – Beri Dec 01 '14 at 07:47
  • 1
    `for i, j in itertools.product(xrange(n), xrange(m)):` is neater, and avoids building the whole list of numbers. – jonrsharpe Dec 01 '14 at 07:47
  • 1
    Also, check [cartesian product of large iterators](http://stackoverflow.com/questions/12093364/cartesian-product-of-large-iterators-itertools) – fredtantini Dec 01 '14 at 07:48
  • Very slow? How fast are you expecting 1.6 billion `print` operations to complete? – Tim Pietzcker Dec 01 '14 at 07:50
  • Why do you want this utterly uninteresting, 1.6 billion line output? My best guess is that it's part of an attempt to brute-force a problem that really isn't amenable to brute force, and you should look for more sophisticated ways to solve the underlying task. – user2357112 Dec 01 '14 at 07:53

2 Answers2

3

You could use a generator:

g = ((i,j) for i in xrange(5) for j in xrange(3))
for tup in g:
    print str(tup[0]) + ',' + str(tup[1])
101
  • 8,514
  • 6
  • 43
  • 69
2

Use itertools.product to produce cartesian product of items.

from itertools import product
list(product(xrange(5), xrange(3)))

[(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2), (3, 0), (3, 1), (3, 2), (4, 0), (4, 1), (4, 2)]

In [13]: %timeit list(product(xrange(5), xrange(3)))
100000 loops, best of 3: 1.98 µs per loop

Your approach:-

for i in range(5):
    for j in range(3):
        print str(i) + ',' + str(j)

100000 loops, best of 3: 7.33 µs per loop

Itertools.product is even faster then generator function (considerable time deiffrence).

def solve():
    a = ((i,j) for i in xrange(5) for j in xrange(3))
    for i in a:
        print i

In [10]: %timeit solve()
100000 loops, best of 3: 3.25 µs per loop
Vishnu Upadhyay
  • 5,043
  • 1
  • 13
  • 24
  • What exactly were you comparing? Your first example doesn't have any `print` statements, your second example has string concatenation and one `print` per loop... – Tim Pietzcker Dec 01 '14 at 07:59
  • @TimPietzcker ohh! i used idle first that's why `print` statement, and i am just ttrying to see the diffrence between OP approach and use of `itertools`. – Vishnu Upadhyay Dec 01 '14 at 08:01