Python - create matrix of tuples - python

I need to create a 9x9 matrix of tuples. I already have a code:
squares, sub = [], []
for y in [3, 6, 9]:
sub.append([[(y, x) for x in range(1, 10) if x % 3 == 0] for x in range(1, 10) if x % 3 == 0])
for i in sub:
sq = []
for j in i:
sq.extend(j)
sq.sort()
squares.append(sq)
squares.append(sq)
squares.append(sq)
with such result:
[[(3, 3), (3, 3), (3, 3), (3, 6), (3, 6), (3, 6), (3, 9), (3, 9), (3, 9)],
[(3, 3), (3, 3), (3, 3), (3, 6), (3, 6), (3, 6), (3, 9), (3, 9), (3, 9)],
[(3, 3), (3, 3), (3, 3), (3, 6), (3, 6), (3, 6), (3, 9), (3, 9), (3, 9)],
[(6, 3), (6, 3), (6, 3), (6, 6), (6, 6), (6, 6), (6, 9), (6, 9), (6, 9)],
[(6, 3), (6, 3), (6, 3), (6, 6), (6, 6), (6, 6), (6, 9), (6, 9), (6, 9)],
[(6, 3), (6, 3), (6, 3), (6, 6), (6, 6), (6, 6), (6, 9), (6, 9), (6, 9)],
[(9, 3), (9, 3), (9, 3), (9, 6), (9, 6), (9, 6), (9, 9), (9, 9), (9, 9)],
[(9, 3), (9, 3), (9, 3), (9, 6), (9, 6), (9, 6), (9, 9), (9, 9), (9, 9)],
[(9, 3), (9, 3), (9, 3), (9, 6), (9, 6), (9, 6), (9, 9), (9, 9), (9, 9)]]
Result is exactly as I want it to be, but do you think there is a better way to write it? Can it be done simpler?
Edit:
Result should be always identical, there isn't any dynamic input and it won't be edited afterwards. Just a static matrix used in a different part of my code.

The question is a bit unclear, as the final list (and the code) might be interpreted, and there might be multiple interpretations with the same result.
For one such interpretation, you could use a (twisted and kind of funny looking) nested list comprehension ([Python 3.Docs]: Data Structures - List Comprehensions):
>>> from pprint import pprint as pp # For print purposes only
>>>
>>> l = [3, 6, 9]
>>>
>>> items = [[i0 for i1 in l for i0 in ((i2, i1),) * len(l)] for i2 in l for _ in l]
>>>
>>> pp(items)
[[(3, 3), (3, 3), (3, 3), (3, 6), (3, 6), (3, 6), (3, 9), (3, 9), (3, 9)],
[(3, 3), (3, 3), (3, 3), (3, 6), (3, 6), (3, 6), (3, 9), (3, 9), (3, 9)],
[(3, 3), (3, 3), (3, 3), (3, 6), (3, 6), (3, 6), (3, 9), (3, 9), (3, 9)],
[(6, 3), (6, 3), (6, 3), (6, 6), (6, 6), (6, 6), (6, 9), (6, 9), (6, 9)],
[(6, 3), (6, 3), (6, 3), (6, 6), (6, 6), (6, 6), (6, 9), (6, 9), (6, 9)],
[(6, 3), (6, 3), (6, 3), (6, 6), (6, 6), (6, 6), (6, 9), (6, 9), (6, 9)],
[(9, 3), (9, 3), (9, 3), (9, 6), (9, 6), (9, 6), (9, 9), (9, 9), (9, 9)],
[(9, 3), (9, 3), (9, 3), (9, 6), (9, 6), (9, 6), (9, 9), (9, 9), (9, 9)],
[(9, 3), (9, 3), (9, 3), (9, 6), (9, 6), (9, 6), (9, 9), (9, 9), (9, 9)]]
Note: Attempting to modify your final list (squares[0][0] = 1) might yield "unexpected" results.

Related

Find all combinations of tuples inside of a list

I am trying to find all permutations of the items inside of the tuples while in the list of length 2. The order of the tuples in relation to each other does not matter.
perm = [(3, 6), (6, 8), (4, 1), (7, 4), (5, 3),
(1, 9), (2, 5), (4, 8), (5, 1), (3, 7),
(6, 9), (10, 2), (7, 10), (8, 2), (9, 10)]
An example of one permutation of the above list would be:
perm = [(6, 3), (6, 8), (4, 1), (7, 4), (5, 3),
(1, 9), (2, 5), (4, 8), (5, 1), (3, 7),
(6, 9), (10, 2), (7, 10), (8, 2), (9, 10)]
Another example permutation would be:
perm = [(6, 3), (8, 6), (1, 4), (4, 7), (3, 5),
(9, 1), (5, 2), (8, 4), (1, 5), (7, 3),
(9, 6), (2, 10), (10, 7), (2, 8), (10, 9)]
In the end, the length of the list of permutations should be 32768, because each tuple is either swapped or not swapped, and 2^15 = 32768. I do not care about the order of the tuples in relation to each other, only the permutations of the items inside of the tuples.
I have tried to use itertools permute, combinations, and product, but I haven't been able to get the desired result.
You can use product:
from itertools import product
lst = [(3, 6), (6, 8), (4, 1), (7, 4), (5, 3),
(1, 9), (2, 5), (4, 8), (5, 1), (3, 7),
(6, 9), (10, 2), (7, 10), (8, 2), (9, 10)]
output = product(*([(x, y), (y, x)] for x, y in lst))
output = list(output) # if you want a list, rather than a generator
print(len(output))
# 32768
print(output[0])
# ((3, 6), (6, 8), (4, 1), (7, 4), (5, 3), (1, 9), (2, 5), (4, 8), (5, 1), (3, 7), (6, 9), (10, 2), (7, 10), (8, 2), (9, 10))
print(output[-1])
# ((6, 3), (8, 6), (1, 4), (4, 7), (3, 5), (9, 1), (5, 2), (8, 4), (1, 5), (7, 3), (9, 6), (2, 10), (10, 7), (2, 8), (10, 9))
The key is to write something like
output = product([(3,6), (6,3)], [(6,8), (8,6)], ..., [(9,10), (10,9)])
in a generic way so that any input list would work, which is done by the generator expression and unpacking (*).

Getting x,y values from two for loops python

I am trying to append numbers from two for loops to make some tuples and add them to a list.
li = []
for x in range(1,10):
for y in range(1,10):
li.append((x,y*2))
print(li)
I am getting this
[(1, 2), (1, 4), (1, 6), (1, 8), (1, 10), (1, 12), (1, 14), (1, 16), (1, 18), (2, 2), (2, 4), (2, 6), (2, 8), (2, 10), (2, 12), (2, 14), (2, 16), (2, 18), (3, 2), (3, 4), (3, 6), (3, 8), (3, 10), (3, 12), (3, 14), (3, 16), (3, 18), (4, 2), (4, 4), (4, 6), (4, 8), (4, 10), (4, 12), (4, 14), (4, 16), (4, 18), (5, 2), (5, 4), (5, 6), (5, 8), (5, 10), (5, 12), (5, 14), (5, 16), (5, 18), (6, 2), (6, 4), (6, 6), (6, 8), (6, 10), (6, 12), (6, 14), (6, 16), (6, 18), (7, 2), (7, 4), (7, 6), (7, 8), (7, 10), (7, 12), (7, 14), (7, 16), (7, 18), (8, 2), (8, 4), (8, 6), (8, 8), (8, 10), (8, 12), (8, 14), (8, 16), (8, 18), (9, 2), (9, 4), (9, 6), (9, 8), (9, 10), (9, 12), (9, 14), (9, 16), (9, 18)]
But it should only be a single x per y combination. How do I fix this?
using list comprehension:
>>> [(x, x**2) for x in range(1, 10)]
[(1, 1), (2, 4), (3, 9), (4, 16), (5, 25), (6, 36), (7, 49), (8, 64), (9, 81)]
using for loop:
>>> li = []
>>> for x in range(1, 10):
... li.append((x, x**2))
...
>>> li
[(1, 1), (2, 4), (3, 9), (4, 16), (5, 25), (6, 36), (7, 49), (8, 64), (9, 81)]
If you have no problems using third party libraries as NumPy, you can also do the following avoiding any explicit for loops.
P.S: For your small example, it might be an overkill but it's good to know alternatives.
The zip here returns an iterator of tuples based on the iterable objects fed as input.
import numpy as np
x = np.arange(1, 10)
print (list(zip(x, x**2)))
# [(1, 1), (2, 4), (3, 9), (4, 16), (5, 25), (6, 36), (7, 49), (8, 64), (9, 81)]

How can I find specific values inside a multidimensional array?

I'm making a game that's a lot like checkers, to create the board I used a multidimensional array. I populate the array with 0's on every empty space and then the one set of chips is represented by 1's and the other is represented by 2's. Is there any way in which I can get a list of what spaces are being occupied by each set of chips? This is my gameboard:
matrix = [[1,1,1,1,1,0,0,0,0,0], [1,1,1,1,0,0,0,0,0,0],
[1,1,1,0,0,0,0,0,0,0], [1,1,0,0,0,0,0,0,0,0],
[1,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,2],
[0,0,0,0,0,0,0,0,2,2], [0,0,0,0,0,0,0,2,2,2],
[0,0,0,0,0,0,2,2,2,2], [0,0,0,0,0,2,2,2,2,2]]
print "\n".join(" ".join(str(el) for el in row) for row in matrix)
You can use list comprehension with condition, following code returns all the spaces occupied by 2:
[(y, x) for y in xrange(len(matrix)) for x in xrange(len(matrix[y])) if matrix[y][x] == 2]
Output:
[(5, 9), (6, 8), (6, 9), (7, 7), (7, 8), (7, 9), (8, 6), (8, 7), (8, 8), (8, 9), (9, 5), (9, 6), (9, 7), (9, 8), (9, 9)]
While list-comprehensions are often a nice way to build a single list, you'll have to go through the entire matrix multiple times to find the positions of every possible chip value. Alternatively, you could create lists of which spaces are occupied by each kind of chip in a single pass through the matrix by doing something like the following:
matrix = [[1,1,1,1,1,0,0,0,0,0], [1,1,1,1,0,0,0,0,0,0],
[1,1,1,0,0,0,0,0,0,0], [1,1,0,0,0,0,0,0,0,0],
[1,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,2],
[0,0,0,0,0,0,0,0,2,2], [0,0,0,0,0,0,0,2,2,2],
[0,0,0,0,0,0,2,2,2,2], [0,0,0,0,0,2,2,2,2,2]]
positions = {}
for y in xrange(len(matrix)):
for x in xrange(len(matrix)):
positions.setdefault(matrix[y][x], []).append((y, x))
# show the all positions of each chip value
for chip in sorted(positions):
print('{}: {}'.format(chip, positions[chip]))
Output:
0: [(0, 5), (0, 6), (0, 7), (0, 8), (0, 9), (1, 4), (1, 5), (1, 6), (1, 7), (1, 8), (1, 9), (2, 3), (2, 4), (2, 5), (2, 6), (2, 7), (2, 8), (2, 9), (3, 2), (3, 3), (3, 4), (3, 5), (3, 6), (3, 7), (3, 8), (3, 9), (4, 1), (4, 2), (4, 3), (4, 4), (4, 5), (4, 6), (4, 7), (4, 8), (4, 9), (5, 0), (5, 1), (5, 2), (5, 3), (5, 4), (5, 5), (5, 6), (5, 7), (5, 8), (6, 0), (6, 1), (6, 2), (6, 3), (6, 4), (6, 5), (6, 6), (6, 7), (7, 0), (7, 1), (7, 2), (7, 3), (7, 4), (7, 5), (7, 6), (8, 0), (8, 1), (8, 2), (8, 3), (8, 4), (8, 5), (9, 0), (9, 1), (9, 2), (9, 3), (9, 4)]
1: [(0, 0), (0, 1), (0, 2), (0, 3), (0, 4), (1, 0), (1, 1), (1, 2), (1, 3), (2, 0), (2, 1), (2, 2), (3, 0), (3, 1), (4, 0)]
2: [(5, 9), (6, 8), (6, 9), (7, 7), (7, 8), (7, 9), (8, 6), (8, 7), (8, 8), (8, 9), (9, 5), (9, 6), (9, 7), (9, 8), (9, 9)]

Iterate list of numbers

I have a list of 13 numbers, each of them can be equal any number from 1 to 9.
I need to look over all possible variants of these numbers in the list: when number1=1 and number2=1/2/3/4/5/6/7/8/9 (exclusive 0), and so on. Then I need to do the same for number1=2 and so on.
I can't quite comprehend how to do it - apparently through 'for' cycle?
for x in range(1,10):
A=[x for i in range(13)]
for i in range(len(A)):
for t in range(1,10):
A[i]=t
print A
This doesn't work out.
I would recommend using itertools.product.
>>> from itertools import product
>>> list(product(range(1, 10), repeat=2))
[(1, 1), (1, 2), (1, 3), (1, 4), (1, 5), (1, 6), (1, 7), (1, 8), (1, 9), (2, 1), (2, 2), (2, 3), (2, 4), (2, 5), (2, 6), (2, 7), (2, 8), (2, 9), (3, 1), (3, 2), (3, 3), (3, 4), (3, 5), (3, 6), (3, 7), (3, 8), (3, 9), (4, 1), (4, 2), (4, 3), (4, 4), (4, 5), (4, 6), (4, 7), (4, 8), (4, 9), (5, 1), (5, 2), (5, 3), (5, 4), (5, 5), (5, 6), (5, 7), (5, 8), (5, 9), (6, 1), (6, 2), (6, 3), (6, 4), (6, 5), (6, 6), (6, 7), (6, 8), (6, 9), (7, 1), (7, 2), (7, 3), (7, 4), (7, 5), (7, 6), (7, 7), (7, 8), (7, 9), (8, 1), (8, 2), (8, 3), (8, 4), (8, 5), (8, 6), (8, 7), (8, 8), (8, 9), (9, 1), (9, 2), (9, 3), (9, 4), (9, 5), (9, 6), (9, 7), (9, 8), (9, 9)]
However, I wouldn't recommend doing it for 13 numbers. Why? Take a look:
>>> len(list(product(range(1, 10), repeat=2)))
81
9^2 = 81. So to compute it for 13, you would need to compute 9^13 tuples with length 13. That will take quite a while.
Luckily itertools.product returns a generator object, so you can iterate through the values one by one if you wish. Just don't try to turn it into a list.

Use Python to create 2D coordinate

I am truly a novice in Python. Now, I am doing a project which involves creating a list of 2D coordinates. The coordinates should be uniformly placed, using a square grid (10*10), like(0,0)(0,1)(0,2)(0,3)...(0,10)(1,0)(1,2)(1,3)...(2,0)(2,1)(2,2)...(10,10).
Here is my code:
coordinate = []
x = 0
y = 0
while y < 10:
while x < 10:
coordinate.append((x,y))
x += 1
coordinate.append((x,y))
y += 1
print(coordinate)
But I can only get: [(0, 0), (1, 0), (2, 0), (3, 0), (4, 0), (5, 0), (6, 0), (7, 0), (8, 0), (9, 0), (10, 0), (10, 1), (10, 2), (10, 3), (10, 4), (10, 5), (10, 6), (10, 7), (10, 8), (10, 9)]
How can I rewrite my code to get all the points?
It's common to use a couple of for-loops to achieve this:
coordinates = []
for x in range(11):
for y in range(11):
coordinates.append((x, y))
It's also common to simplify this by flattening it into a list comprehension:
coordinates = [(x,y) for x in range(11) for y in range(11)]
from itertools import product
x = (0, 1, 2)
test = product(x, x)
Result:
>>> for ele in test:
... print ele
...
(0, 0)
(0, 1)
(0, 2)
(1, 0)
(1, 1)
(1, 2)
(2, 0)
(2, 1)
(2, 2)
Note that test is a generator, so you probably would want to use list(test).
To actually answer your question, you forgot to reset x back to zero after the first run through x=0..9:
coordinate = []
y = 0
while y < 10:
x = 0
while x < 10:
coordinate.append((x,y))
x += 1
coordinate.append((x,y))
y += 1
print(coordinate)
Feel free to use all other variants, of course.
Use itertools.product:
>>> from itertools import product
>>> list(product(range(11), repeat=2))
[(0, 0), (0, 1), (0, 2), (0, 3), (0, 4), (0, 5), (0, 6), (0, 7), (0, 8), (0, 9), (0, 10), (1, 0), (1, 1), (1, 2), (1, 3), (1, 4), (1, 5), (1, 6), (1, 7), (1, 8), (1, 9), (1, 10), (2, 0), (2, 1), (2, 2), (2, 3), (2, 4), (2, 5), (2, 6), (2, 7), (2, 8), (2, 9), (2, 10), (3, 0), (3, 1), (3, 2), (3, 3), (3, 4), (3, 5), (3, 6), (3, 7), (3, 8), (3, 9), (3, 10), (4, 0), (4, 1), (4, 2), (4, 3), (4, 4), (4, 5), (4, 6), (4, 7), (4, 8), (4, 9), (4, 10), (5, 0), (5, 1), (5, 2), (5, 3), (5, 4), (5, 5), (5, 6), (5, 7), (5, 8), (5, 9), (5, 10), (6, 0), (6, 1), (6, 2), (6, 3), (6, 4), (6, 5), (6, 6), (6, 7), (6, 8), (6, 9), (6, 10), (7, 0), (7, 1), (7, 2), (7, 3), (7, 4), (7, 5), (7, 6), (7, 7), (7, 8), (7, 9), (7, 10), (8, 0), (8, 1), (8, 2), (8, 3), (8, 4), (8, 5), (8, 6), (8, 7), (8, 8), (8, 9), (8, 10), (9, 0), (9, 1), (9, 2), (9, 3), (9, 4), (9, 5), (9, 6), (9, 7), (9, 8), (9, 9), (9, 10), (10, 0), (10, 1), (10, 2), (10, 3), (10, 4), (10, 5), (10, 6), (10, 7), (10, 8), (10, 9), (10, 10)]
The above code is equivalent to this nested list comprehension:
>>> [(x, y) for x in range(11) for y in range(11)]
[(0, 0), (0, 1), (0, 2), (0, 3), (0, 4), (0, 5), (0, 6), (0, 7), (0, 8), (0, 9), (0, 10), (1, 0), (1, 1), (1, 2), (1, 3), (1, 4), (1, 5), (1, 6), (1, 7), (1, 8), (1, 9), (1, 10), (2, 0), (2, 1), (2, 2), (2, 3), (2, 4), (2, 5), (2, 6), (2, 7), (2, 8), (2, 9), (2, 10), (3, 0), (3, 1), (3, 2), (3, 3), (3, 4), (3, 5), (3, 6), (3, 7), (3, 8), (3, 9), (3, 10), (4, 0), (4, 1), (4, 2), (4, 3), (4, 4), (4, 5), (4, 6), (4, 7), (4, 8), (4, 9), (4, 10), (5, 0), (5, 1), (5, 2), (5, 3), (5, 4), (5, 5), (5, 6), (5, 7), (5, 8), (5, 9), (5, 10), (6, 0), (6, 1), (6, 2), (6, 3), (6, 4), (6, 5), (6, 6), (6, 7), (6, 8), (6, 9), (6, 10), (7, 0), (7, 1), (7, 2), (7, 3), (7, 4), (7, 5), (7, 6), (7, 7), (7, 8), (7, 9), (7, 10), (8, 0), (8, 1), (8, 2), (8, 3), (8, 4), (8, 5), (8, 6), (8, 7), (8, 8), (8, 9), (8, 10), (9, 0), (9, 1), (9, 2), (9, 3), (9, 4), (9, 5), (9, 6), (9, 7), (9, 8), (9, 9), (9, 10), (10, 0), (10, 1), (10, 2), (10, 3), (10, 4), (10, 5), (10, 6), (10, 7), (10, 8), (10, 9), (10, 10)]
Use a for loop. It lets you iterate over things called "iterators". range is a built-in function which returns an iterator from its starting argument (first argument) inclusive. up to its ending argument (second argument) non-inclusive. Thus range(0,11) will return 0,1,2,...,10.
coordinate = []
for y in range(0, 11):
for x in range(0, 11):
coordinate.append((x,y))
print(coordinate)
For more information on for loops in Python, check out the official wiki page.

Categories

Resources