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

Posted

技术标签:

【中文标题】n power n print \'Hello World\' 不计算值【英文标题】:n power n print 'Hello World' without calculating the valuen power n print 'Hello World' 不计算值 【发布时间】:2018-03-21 06:30:11 【问题描述】:

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

例如,

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

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

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

提前谢谢你。

【问题讨论】:

范围是允许的,但您的答案将始终给出n**2。我要n**n 这基本上是不可能的(在Python 3中),因为print也是一个内置函数。 这不是“做我的功课”网站...您尝试了什么? 这不是我的作业。这是在一次采访中被问到的,我尝试了很多东西。我可以到达广场,但不能到达n**n。内置函数是指计算指数的函数,如 ** 或 math.power 等。 编写一个ntimes 高阶函数,将其参数连续n次应用于其参数的参数。用n 调用ntimes 本身,然后调用partial(print, 'Hello World') 上的结果。 【参考方案1】:

第一:

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 不太好用,因为它返回None,所以你不能自己组合它。所以:

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 编码并对两个 Church 数字求幂,然后将其与我的代码进行比较。那么,我真的避免计算n**n的值了吗?


当然,您可以使用简单的平面递归和没有高阶函数或使用itertools 来更简单地做到这一点(好吧,您不允许使用内置函数,但 itertools 中的所有内容都带有源代码和/或文档中的“大致等效”功能,因此您可以复制它)。但这有什么乐趣呢?毕竟,如果你真的想要一个 Pythonic、简单或高效的版本,你只需遍历range(n**n)。我认为这个面试问题的重点是迫使你跳出 Pythonic 的框框思考。

【讨论】:

效果很好。谢谢你。我还是有点迷茫,想一步一步去理解。 @binu.py 太好了!尝试使用 1,然后 2,然后再处理 3。(不要尝试 0,因为我忘记处理了……)也许也可以尝试 thrice(twice)twice(thrice)。此外,想想你确实理解的高阶函数,例如mapfunctools.partial,并了解它们的工作原理。 当然。谢谢@abarnert 我现在明白了。 第二天重读这篇文章,我的血液里有更多的咖啡……我为什么不把它写成用教堂数字编码整数呢?这将允许一个有用的解释性链接,同时允许我使代码对 Python 来说更加荒谬。【参考方案2】:
>>> 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 的值只需要打印【参考方案3】:

只是为了好玩并给出一个有启发性的答案,你可以用一个非常简单的递归函数来做到这一点,而无需计算 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 很棒的解决方案!

最好的,翁贝托

【讨论】:

以上是关于n power n print 'Hello World' 不计算值的主要内容,如果未能解决你的问题,请参考以下文章

python怎么用一个print换行输出多个变量

python怎么用一个print换行输出多个变量

字符串基本操作

python print及格式化

面向对象

python 基本语句