繁体   English   中英

Python 中使用生成器的阶乘程序

[英]Factorial Program in Python using generator

#function
def fact(x):
    a = 1
    b = 1
    if x == 0:
        a = 1
    if x < 0:
        print('enter valid whole number!')
    if x > 0:
        while b < x:
            a = a * b
            b += 1
    yield a
#main
z = input('Enter a number')
g = (fact(n) for n in range (0,int(z)))
print(next(g))

当我运行上面的程序时,output 在某个块显示生成器 object,如下所示:

Enter a number4
<generator object fact at 0x03DF6930>

g是一个生成器,它调用fact并产生结果。 fact也是一个生成器。 你有两个生成器,所以你需要两个next调用。

z = 3
g = (fact(n) for n in range (0,int(z)))
print(next(next(g)))

结果:

1

或者,将fact转换为常规的旧非生成器函数,因为如果您只需要从可调用对象中检索单个值,那么使用yield没有多大意义。

def fact(x):
    a = 1
    b = 1
    if x == 0:
        a = 1
    if x < 0:
        print('enter valid whole number!')
    if x > 0:
        while b < x:
            a = a * b
            b += 1
    return a
#main
z = 3
g = (fact(n) for n in range (0,int(z)))
print(next(g))

结果:

1

也许你在想“但我真正想做的是计算 O(N) 时间内的前 N ​​个阶乘值(假设任意大整数的乘法是 O(1)),并且将我的函数更改为使用return意味着我将不得不重新计算很多旧值。有人告诉我, yield可能会提高性能,但我的第一次尝试没有奏效,那我该怎么做?”。 也许他们想让你写一些类似的东西:

def factorials_up_to(x):
    a = 1
    for i in range(1, x+1):
        a *= i
        yield a

for x in factorials_up_to(6):
    print(x)

结果:

1
2
6
24
120
720

有很多方法可以解决这个问题。 但是,我个人的偏好是创建一个无限对象,其中每个元素仅在需要时才加载。 用户warnabas建议使用itertools库来执行此操作,但可以(且更简单)避免这种情况。

def fac(n, t):
    '''This creates a generator for the sequence of factorial
    numbers.'''

    yield t
    yield from fac(n+1, n*t)

f = fac(1,1)

然后我们可以随意使用这个生成器。 例如,代码

z = int(input('Enter a number: ')) +1
for i in range(z):
    print(next(f))

提示用户输入一个数字,然后打印直到并包括 z! 的阶乘序列。

import itertools


def factorial_generator():
    i, fac = 1, 1
    while True:
        yield fac
        fac *= i
        i += 1

def factorial(n):
    return next(itertools.islice(factorial_generator(), n, None))

实际上,您应该构建无限序列来制作真正的生成器。

# factorial function, recursively compute factorial
def fact(n):
    if n==1:
        # base case
        return 1
    else:
        # recursive case
        return n*fact(n-1)

# upto desired number computer the factorial function
def upto(n):
    for i in range(1,n+1):
        yield fact(i)

# call function
f=upto(3)
# print (it will print object not its contents)
print(f)
# to print use __next__ method to show each value
print(f.__next__())
print(f.__next__())
print(f.__next__())

还有另一种方法通过生成器使用 function 和 for 循环打印阶乘
方法 - 1

def fact(n):
value = 1
for i in range(1,n+1):
     value *= i
     yield value
f = fact(int(input('Enter the number : ')))

print(next(f))
print(next(f))
print(next(f))
print(next(f))

Output:

Enter the number : 4
1
2
6
24

方法 - 2

def fact(n):
value = 1
for i in range(1,n+1):
     value *= i
     yield value

f = fact(int(input('Enter the number : ')))

for value in f:
    print(value)

Output:

Enter the number : 4
1
2
6
24
def get_factorial(num):
    factorial = 1
    for x in (i for i in range(num)):
        factorial *= x+1

    return factorial

def main():

    print(get_factorial(5))


if __name__ == "__main__":
    main()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM