13

I'm not looking for solution, I'm looking for a better solution or just a different way to do this by using some other kind of list comprehension or something else.

I need to generate a list of tuples of 2 integers to get map coordinates like [(1, 1), (1, 2), ..., (x, y)]

So I have the following:

width, height = 10, 5

Solution 1

coordinates = [(x, y) for x in xrange(width) for y in xrange(height)]

Solution 2

coordinates = []
for x in xrange(width):
    for y in xrange(height):
        coordinates.append((x, y))

Solution 3

coordinates = []
x, y = 0, 0
while x < width:
    while y < height:
        coordinates.append((x, y))
        y += 1
    x += 1

Are there any other solutions? I like the 1st one most.

4
  • 2
    I'm fairly sure solution 1 is the best you can come up with. Commented Jan 31, 2012 at 16:11
  • What do you intend to do with the list of coordinates? Commented Jan 31, 2012 at 19:43
  • At first I'm just writing them to the database to generate a RPG game map for 2D browser game. Commented Feb 1, 2012 at 9:16
  • +1 for the first solution by using list comprehension ... Commented Jul 19, 2012 at 14:55

3 Answers 3

17

Using itertools.product():

from itertools import product
coordinates = list(product(xrange(width), xrange(height)))
Sign up to request clarification or add additional context in comments.

3 Comments

itertools is a computational saviour.
+1. I would put it in a function, so that you can just pass in width and height and get the list back.
Well, I've just done some testing and got the following: creating a generator by list comprehension without [] is the fastest way, but if we are looping through the data afterwards then your method is much faster. Thanks!:)
6

The first solution is elegant, but you could also use a generator expression instead of a list comprehension:

((x, y) for x in range(width) for y in range(height))

This might be more efficient, depending on what you're doing with the data, because it generates the values on the fly and doesn't store them anywhere.

This also produces a generator; in either case, you have to use list to convert the data to a list.

>>> list(itertools.product(range(5), range(5)))
[(0, 0), (0, 1), (0, 2), (0, 3), (0, 4), (1, 0), (1, 1), (1, 2), 
 (1, 3), (1, 4), (2, 0), (2, 1), (2, 2), (2, 3), (2, 4), (3, 0), 
 (3, 1), (3, 2), (3, 3), (3, 4), (4, 0), (4, 1), (4, 2), (4, 3), (4, 4)]

Note that if you're using Python 2, you should probably use xrange, but in Python 3, range is fine.

2 Comments

Using xrange in the itertools.product class would be more memory efficient, like F.J. did.
@NiklasR, assuming this is Python 2. If it's Python 3, xrange no longer exists. Adding a note though.
-1

UPDATED: Added @F.J. answer in the benchmark

The first implementation is the most pythonic way, and seems to be the fastest, too. Using 1000 for each, width and height, I register execution-times of

  1. 0.35903096199s
  2. 0.461946964264s
  3. 0.625234127045s

@F.J 0.27s

So yeah, his answer is the best.

1 Comment

I assume the first implementation is F.J.'s itertools solution? And you should provide better descriptions for the numbers.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.