Python整数分区

Python整数分区,python,numbers,Python,Numbers,我正试图写一段代码,给我一个数字的分区。到目前为止,我想出了这个(在谷歌上找到) def发生器(n): #元组版本 如果n==0: 产量() 返回 对于发电机(n-1)中的p: 收益率(1,)+p 如果p和(len(p)p[0]): 收益率(p[0]+1,)+p[1:] 打印(列表(gen(5))) 如果有人能帮助我理解这个递归函数是如何工作的,我将不胜感激。请帮助。谢谢。将函数转换为生成器。请阅读以获得良好的解释 基本上,不是立即创建结果列表然后返回: def f(): output

我正试图写一段代码,给我一个数字的分区。到目前为止,我想出了这个(在谷歌上找到)

def发生器(n):
#元组版本
如果n==0:
产量()
返回
对于发电机(n-1)中的p:
收益率(1,)+p
如果p和(len(p)p[0]):
收益率(p[0]+1,)+p[1:]
打印(列表(gen(5)))
如果有人能帮助我理解这个递归函数是如何工作的,我将不胜感激。请帮助。谢谢。

将函数转换为生成器。请阅读以获得良好的解释

基本上,不是立即创建结果列表然后返回:

def f():
    output = []

    for i in range(10):
        output.append(i + 3)

    return output
您可以创建一个生成器,仅当您请求一个时,该生成器才能生成项:

def f():
    for i in range(10):
        yield i + 3
也可以制作无限多个生成器:

def f():
    a = 0
    b = 1

    while True:
        yield b

        a, b = b, a + b

迭代
f()
只会不断吐出斐波那契序列的项。

为了了解发生了什么,它有助于打印生成器的输出,以获得几个连续递增的值
n

>>> for i in range(5):
        print(list(gen(i)))

[()]
[(1,)]
[(1, 1), (2,)]
[(1, 1, 1), (1, 2), (3,)]
[(1, 1, 1, 1), (1, 1, 2), (2, 2), (1, 3), (4,)]
每个序列的计算都基于它之前的序列。下面逐行解释它的工作原理:

if n == 0:
    yield ()
    return
生成器的前几行用于基本情况,其中
n
为零。
return
语句使其在生成空元组后退出,而不是继续处理其余代码

for p in gen(n-1):
这是函数的递归步骤。由于
gen
是一个生成器,它是通过循环完成的,因此剩余的代码将重复运行
p
并从递归结果中获取不同的值

    yield (1, ) + p
这是一条重要的路线。这样做的目的是从生成器中产生一个新的元组,它是通过将
1
连接到值
p
的前面而形成的。如果
p
是空元组,则这将是一个1元组。如果
p
已经有一些值,元组将变长

    if p and (len(p)<2 or p[1] > p[0]):
这是另一个元组连接。它将
p
的第一个值增加1,然后将其与
p
的其余部分连接(使用一个切片)。所以
(3,)
将变成
(4,)
(片为空),
(1,2)
变成
(2,2)
,等等

现在让我们来看一下上面的结果

[()]
n
等于0时,将命中基本大小写,得到一个空元组

[(1,)]
n
等于1时,循环运行一次,并将
(1,)
连接到空元组上,生成1元组
(1,)
。由于
p
为空,因此未通过
条件的第一部分

[(1,1), (2,)]
n
等于2时,循环仍然只运行一次。首先,它将
(1,1)
与自身连接,得到
(1,1)
。但是这次,运行
if
块是因为
p
只有一个值。因此它也会产生
(p[0]+1,)+p[1:
。它的切片部分是空元组,但第一部分是
(2,)

现在,循环终于可以运行不止一次了!不过,第一次,它将另一个
(1,)
连接到
(1,1)
的前面,因为
如果不满足
语句的条件,它只会这样做。但是,在第二次传递时,它产生两个值,一次连接
(1,)
(2,)
,然后将
(2,)
增加到
(3,)


这个我留给你,让你走过去。与上述情况一样,
p
将接受上一级调用中的每个值(
(1,1,1),(1,2),(3),)
)对于每一个值,它将产生一个或两个新结果。

您对哪一部分感到困惑?如果您能解释每一行,我将非常高兴。这将帮助我更好地理解收益率是如何工作的。感谢您可能的重复我以前读过,我确实理解收益率是如何工作的。但这并不能回答我的问题问题。我仍然不明白他为什么写yield()然后返回,以及为什么写yield(1,)+p。这让我很困惑。你能给我解释一下这是如何工作的吗。谢谢。1)所有生成器在
生成最终结果后必须
返回
。通常,当它们从函数底部脱落时,返回是隐式的。(沉思)2)
yield(1,)+p
是他的递归算法的一部分。该表达式创建一个元组,其中
1
作为初始元素,
p
的成员作为剩余元素。例如,如果
(2,2)
是数字4的一个分区,那么
(1,2,2)
是数字5的一个分区。谢谢你,但我已经知道你写了什么。问题是我不明白他为什么写yield()然后返回,以及为什么这个->yield(1,)+p有效。你能解释一下吗?我真的很感谢你写的东西,感谢你花时间写这一切。这对我有很大帮助,我希望它也能帮助其他人。@SerjCodito如果这个答案对你有帮助,并且你觉得它充分回答了你的问题,你应该接受它(可能还有向上投票)
[(1,)]
[(1,1), (2,)]
[(1,1,1), (1,2), (3,)]
[(1, 1, 1, 1), (1, 1, 2), (2, 2), (1, 3), (4,)]