Creating tuples using a variable number of for loops

半城伤御伤魂 提交于 2021-02-10 12:15:41

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!