【问题标题】:Creating tuples using a variable number of for loops使用可变数量的 for 循环创建元组
【发布时间】:2019-12-05 18:10:11
【问题描述】:

给定nk,我需要创建所有长度为k 的元组,其条目来自range(n)(0 到 n-1),这样元组的条目按字典顺序排列并且有括号以特定格式。具体来说,元组从内到外在每一对周围都有括号。

例如,如果n=3k=4,那么我希望输出包含(((0,0),1),2) 之类的内容,但 包含(((0,0),2),1) 之类的内容。

下面的代码适用于这个特定的实例。问题是我不知道如何概括k,这是下面代码中的for 循环数。我只能为特定的k 执行此操作,例如此处的k=4。我真的需要能够为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

输出:

[(((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)]

【问题讨论】:

  • k 是从哪里来的?是for 循环的数量吗?
  • 请问这样做的目的是什么?
  • @user1558604:是的,k 是 for 循环的数量。
  • 我不知道它是否是建模这个“算法”的最佳方法,但如果你想改变循环的数量,你可以将它转换为递归 k 次的递归函数......只要因为 k 不会变得太大并达到最大递归限制
  • 那么您在 Python 中有一个图形并且想要删除“冗余”顶点?所以例如(((0,0),1),2) 等于(((0,0),2),1)?

标签: python for-loop variables tuples python-2.x


【解决方案1】:

另一种解决方案,基于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')

打印:

(((0, 0), 0), 0)
(((0, 0), 0), 1)
(((0, 0), 0), 2)
(((0, 0), 0), 3)
(((0, 0), 1), 1)
...and so on.

【讨论】:

  • 很好,尽管您应该通过适当的函数定义来更改 f。
【解决方案2】:

以下应该可以工作。

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)]

基本情况会在结果中精确生成您需要的元组。

从递归情况产生的每个元组(x,y),我们创建一组元组((x, y), z)z >= y

【讨论】:

    【解决方案3】:

    试试这个,我希望它是相关的:

    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
    

    输出

    [(((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)]

    【讨论】:

    • 这仅适用于固定的k;对 any k. 有效的东西的请求
    【解决方案4】:

    你见过 itertools 内置库吗? https://docs.python.org/3.1/library/itertools.html?highlight=combinations#itertools.combinations_with_replacement

    乍一看您的问题,看起来您实际上是在创建一个包含替换的所有组合的列表(尽管您真的想使用 k+1)。这不会有“嵌套”属性,但它会给你准确的数字,我想调整结构比提出你需要的递归算法要容易得多。这是一个例子:

    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), ...]
    

    【讨论】:

    • 我已经看到了。真正的问题在于嵌套的括号。
    猜你喜欢
    • 2017-05-26
    • 1970-01-01
    • 2015-12-26
    • 2016-05-08
    • 2018-02-18
    • 2012-01-21
    • 2018-02-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多