Somebody beat me to it in the comments, but I have some timing information for you. Note that your times may vary, but relative times should be fairly representative of the performance you might see.
First your code, which I fixed to make runnable:
cards = []
for figure in range(2, 15):
for suite in [1, 2, 3, 4]:
card = [figure, suite]
cards.append(card)
# 8.04 µs ± 27.5 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
So 8.04 microseconds is the time to beat! Using numpy.mgrid:
import numpy as np
cards = np.mgrid[1:5, 2:15]
# 20.5 µs ± 320 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
Surprisingly much slower. I wonder if something isn't set up ideally on my system for numpy. I still recommend trying it on your system (use the %%timeit cell magic in a Jupyter notebook for easy profiling).
Next using itertools.product:
import itertools as it
figures = range(2, 15)
suits = [1, 2, 3, 4]
cards = list(it.product(suits, figures))
# 2.5 µs ± 27.3 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
Faster! And the best news is that it.product() returns an iterator instead of creating the list when called, so if you don't need the actual card list until later, you can defer creating the list and just pass the iterator around. Creating the iterator is the fastest by far:
cards_it = it.product(suits, figures) # notice no 'list'
# 479 ns ± 9.5 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
That's 5-10 times faster than anything else!
list(itertools.product(range(2,15), [1,2,3,4]))is a good way of generating these 52 pairs.cards = np.mgrid[1:5,2:15]