tags:

views:

325

answers:

4

I am new to python and don't know the best way to do this.

I have a list of tuples which represent points and another list which represents offsets. I need a set of all the combinations that this forms. Here's some code:

offsets = [( 0, 0),( 0,-1),( 0, 1),( 1, 0),(-1, 0)]
points = [( 1, 5),( 3, 3),( 8, 7)]

So my set of combined points should be

[( 1, 5),( 1, 4),( 1, 6),( 2, 5),( 0, 5),
 ( 3, 3),( 3, 2),( 3, 4),( 4, 3),( 2, 3),
 ( 8, 7),( 8, 6),( 8, 8),( 9, 7),( 7, 7)]

I'm not able to use NumPy or any other libraries.

+4  A: 

Pretty simple:

>>> rslt = []
>>> for x, y in points:
...     for dx, dy in offsets:
...         rslt.append( (x+dx, y+dy) )
... 
>>> rslt
[(1, 5), (1, 4), (1, 6), (2, 5), (0, 5), (3, 3), (3, 2), (3, 4), (4, 3), (2, 3), (8, 7), (8, 6), (8, 8), (9, 7), (7, 7)]

Cycle through the points and the offsets, then build new tuples of adding the offsets to the points.

Joel
+10  A: 
result = [(x+dx, y+dy) for x,y in points for dx,dy in offsets]

For more, see list comprehensions.

Alok
I was trying to find a more clever way using itertools, but I couldn't. This answer looks ideal to me.
darkporter
Pretty cool. I didn't know that you could nest `for` like that.
rlbond
+1  A: 

If you don't care about duplicates in the result:

result = []
for ox, oy in offsets:
    for px, py in points:
        result.append((px + ox, py + oy))

If you do care about duplicates in the result:

result = set()
for ox, oy in offsets:
    for px, py in points:
        result.add((px + ox, py + oy))
John Machin
+4  A: 

Personally, I like Alok's answer. However, for fans of itertools, the itertools-based equivalent (in Python 2.6 and later) is:

import itertools as it
ps = [(x+dx, y+dy) for (x, y), (dx, dy) in it.product(points, offsets)]

However, in this case the itertools solution is not faster than the simple one (it's actually a tad slower because it needs to unpack each x, y repeatedly for every offset, while Alok's simple approach unpacks each x, y but once). Still, itertools.product is an excellent alternative to nested loops in other cases, so, it's worth knowing about it!-)

Alex Martelli
It’s also worth noting that the combinatoric functions itertools.product, itertools.permutations, and itertools.combinations are new in Python 2.6.
OK, done (though it gets very tiresome to explain what Python release each feature was introduced each and every time you mention any Python feature at all, you know!-).
Alex Martelli