问题
Given n
and k
, I need to create all tuples of length k
whose entries are from range(n)
(0 to n-1) such that the tuple's entries are in dictionary order and there are parentheses in a particular format. Specifically, the tuple has parentheses around each pair, from inside out.
For example, if n=3
and k=4
, then I would like the output to include something like (((0,0),1),2)
, but not something like (((0,0),2),1)
.
The code below works for this specific instance. The issue is that I don't know how to generalize on k
, which is the number of for
loops in the code below. I can only do this for a specific k
, like k=4
here. I really need to be able to do this for any value of k
.
n=3
k=4
my_list = []
for a in range(n):
x = a
for b in range(a,n):
y = (x,b)
for c in range(b,n):
z = (y,c)
for d in range(c,n):
w = (z,d)
my_list.append(w)
print my_list
Output:
[(((0, 0), 0), 0), (((0, 0), 0), 1), (((0, 0), 0), 2), (((0, 0), 1), 1), (((0, 0), 1), 2), (((0, 0), 2), 2), (((0, 1), 1), 1), (((0, 1), 1), 2), (((0, 1), 2), 2), (((0, 2), 2), 2), (((1, 1), 1), 1), (((1, 1), 1), 2), (((1, 1), 2), 2), (((1, 2), 2), 2), (((2, 2), 2), 2)]
回答1:
Another solution, based on itertools.combinations_with_replacement
:
import itertools
n, k = 4, 4
f = lambda x: (f(x[:-1]), x[-1]) if len(x)>2 else x
print(*map(f, itertools.combinations_with_replacement(range(n), k)), sep='\n')
Prints:
(((0, 0), 0), 0)
(((0, 0), 0), 1)
(((0, 0), 0), 2)
(((0, 0), 0), 3)
(((0, 0), 1), 1)
...and so on.
回答2:
The following should work.
def tuples(n, k):
if k == 2:
return [(i,j) for i in range(n) for j in range(i, n)]
else:
return [(t, m) for t in tuples(n, k-1) for m in range(t[1], n)]
The base case generates precisely the tuples you need in the result.
From each tuple (x,y)
produced by the recursive case, we create a set of tuples ((x, y), z)
with z >= y
.
回答3:
Try this out, I hope it is relevant:
n=4
k=4
my_list=[(((a,b),c),d) for a in range(n) for b in range(a,n) for c in range(b,n) for d in range(c,n) ]
print my_list
Output:
[(((0, 0), 0), 0), (((0, 0), 0), 1), (((0, 0), 0), 2), (((0, 0), 0), 3), (((0, 0), 1), 1), (((0, 0), 1), 2), (((0, 0), 1), 3), (((0, 0), 2), 2), (((0, 0), 2), 3), (((0, 0), 3), 3), (((0, 1), 1), 1), (((0, 1), 1), 2), (((0, 1), 1), 3), (((0, 1), 2), 2), (((0, 1), 2), 3), (((0, 1), 3), 3), (((0, 2), 2), 2), (((0, 2), 2), 3), (((0, 2), 3), 3), (((0, 3), 3), 3), (((1, 1), 1), 1), (((1, 1), 1), 2), (((1, 1), 1), 3), (((1, 1), 2), 2), (((1, 1), 2), 3), (((1, 1), 3), 3), (((1, 2), 2), 2), (((1, 2), 2), 3), (((1, 2), 3), 3), (((1, 3), 3), 3), (((2, 2), 2), 2), (((2, 2), 2), 3), (((2, 2), 3), 3), (((2, 3), 3), 3), (((3, 3), 3), 3)]
回答4:
Have you seen the itertools builtin library? https://docs.python.org/3.1/library/itertools.html?highlight=combinations#itertools.combinations_with_replacement
At first glance at your issue, It looks like you're essentially creating a list of all combinations with replacement (although, you would really want to use k+1). This would not have the "nested" property, but it would give you exactly the numbers you want, and I imagine adjusting the structure would be much easier than coming up with the recursive algorithm you would need to do it your way. Here's an example:
import itertools
n = 3
k = 4
choices = range(n)
output = list(itertools.combinations_with_replacement(choices, k + 1)
# output = [(0, 0, 0, 0), (0, 0, 0, 1), ...]
来源:https://stackoverflow.com/questions/59200990/creating-tuples-using-a-variable-number-of-for-loops