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)
。此外,想想你确实理解的高阶函数,例如map
或functools.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' 不计算值的主要内容,如果未能解决你的问题,请参考以下文章