n power n print 'Hello World' 不计算值

n power n print 'Hello World' without calculating the value

我想打印 Hello World n**n 次而不计算 python 中 n**n 的值。

例如,

如果 n 是 2,它应该打印 'Hello World' 4 次。

如果 n 是 3,它应该打印 'Hello World' 27 次等等。

我可以使用循环和递归,但现在可以使用任何内置函数或计算 n **n 的值并打印多次。

提前致谢。

第一个:

def compose(f, g):
    def wrapper(x):
        return f(g(x))
    wrapper.__name__ = f'compose({f.__name__}, {g.__name__})'
    return wrapper

def ntimes(n):
    def wrap(func):
        if n == 1: return func
        return compose(func, ntimes(n-1)(func))
    return wrap

这应该是显而易见的,对吧? ntimes(3) 是一个函数,它可以将任何函数与自身组合 3 次,所以 ntimes(3)(func)(x)func(func(func(x))).

现在,我们只需要在 ntimes 上调用 ntimes,在两个级别上使用相同的 n。我可以编写一个 nntimes 函数,以与 ntimes 相同的方式执行此操作,但为了多样化,让我们让它更平坦:

def nntimes(n, func, arg):
    f = ntimes(n)
    return f(f)(func)(arg)

所以 nntimes(n, func, arg)ntimes(n) 上调用 ntimes(n),它给你一个函数,该函数将其参数组合 n**n 次,然后在 arg 上调用该函数].

而现在我们只需要一个函数传入即可。print不太行,因为它returnsNone,所以你不能和它自己组合。所以:

def printret(x):
    print(x, end=' ')
    return x

现在我们只称它为:

>>> nntimes(2, printret, 'Hi')
hi hi hi hi
>>> nntimes(3, printret, 'Hi')
hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi

如果您仍然不明白发生了什么,也许这会有所帮助。让我们做一些比一般的 nntimes 更简单的事情,只硬编码三个,然后打印出组成:

>>> thrice = ntimes(3)
>>> print(thrice(thrice)(printret).__name__)
compose(compose(compose(printret, compose(printret, printret)), compose(compose(printret, compose(printret, printret)), compose(printret, compose(printret, printret)))), compose(compose(compose(printret, compose(printret, printret)), compose(compose(printret, compose(printret, printret)), compose(printret, compose(printret, printret)))), compose(compose(printret, compose(printret, printret)), compose(compose(printret, compose(printret, printret)), compose(printret, compose(printret, printret))))))

所有这些括号!就好像死了去Lisp!


如果你继续阅读 Church numerals,你会发现我有点作弊。写出 Church-encode 一个数字并使两个教会数字取幂的简单函数,然后将其与我的代码所做的进行比较。那么,我真的避免了计算n**n的值吗?


当然,您可以使用简单的平面递归而不使用 higher-order 函数,或者使用 itertools 来更简单地完成此操作(好吧,您不能使用内置函数,但是itertools 中的所有内容都带有源代码 and/or 或文档中的 "roughly equivalent" 函数,因此您可以复制它)。但这有什么乐趣呢?毕竟,如果您真的想要一个 Pythonic、简单或高效的版本,您只需循环 range(n**n)。我假设这个面试问题的重点是迫使你跳出 Pythonic 的框框思考。

>>> def new(number,loop):
...     if loop == 1:
...         return number
...     else:
...         return number * new(number,loop-1)
... 
>>> a = new(3,3)
>>> print a
27
>>> print "Hello "*a
Hello Hello Hello Hello Hello Hello Hello Hello Hello Hello Hello Hello Hello Hello Hello Hello Hello Hello Hello Hello Hello Hello Hello Hello Hello Hello Hello 

只是为了好玩和给出一个有启发性的答案,你可以用一个非常简单的递归函数这样做,而不需要计算 n**n:

def fun(n, level):
    if (level == n):
        print('Hello World')
        return 
    for i in range (n):
        fun(n, level+1)

如果你尝试

fun(2,0)

你得到

Hello World
Hello World
Hello World
Hello World

同样适用于 fun(3,0)...希望对您有所帮助。是一个相当简单的解决方案。 @abarnert 绝妙的解决方案!

最好的,翁贝托