我如何不在lambda中重复列表理解

时间:2019-06-05 17:49:44

标签: python python-3.x

我试图不必要地幻想来自codesignal的挑战。问题是:“给出一个数字和一个范围,找到在给定范围内可被给定数字整除的最大整数。”

我有l的左边界,r的右边界,和d的除数。如果边界内的数字均不可除,则该函数必须返回-1。否则,返回最大的可除数。

是否有避免重复列表理解的方法? 有没有更好的方法可以完全做到这一点? (当然,这同样是不可读和不必要的)

这些会收到一个NameError: name '_' is not defined,这很有意义。

maxDivisor = lambda l,r,d: _[0] if [i for i in range(l,r+1)[::-1] if i%d==0] else -1

maxDivisor = lambda l,r,d: [i for i in range(l,r+1)[::-1] if i%d==0][0] if _ else -1

这可行,但是我不想重复自己:

maxDivisor = lambda l,r,d: [i for i in range(l,r+1)[::-1] if i%d==0][0] if [i for i in range(l,r+1)[::-1] if i%d==0] else -1

这可行,但是太易读了:

def maxDivisor(left, right, divisor):
    for i in range(left,right+1)[::-1]:
        if i%divisor ==0:
            return i
    return -1

只需重申一下: maxDivisor(-99,-96,5)应该返回-1并且 maxDivisor(1,10,3)应该返回9

感谢您对我不必要的请求的帮助。

1 个答案:

答案 0 :(得分:2)

不要仅仅为了编写错误和不可读的代码而编写错误和不可读的代码。 1)

相反,我建议将max与生成器表达式和默认值一起使用,该默认值并读取正是您想要的:获取此范围内的最大数字为除数;如果不存在除数,则为-1。

res = max((x for x in range(l, r+1) if x%d==0), default=-1)

与之类似,但可能更接近您的尝试,您可以在过滤后的反向范围上使用next以获得最大的此类元素,或者默认为-1。

res = next((x for x in range(r, l-1, -1) if x%d==0), -1)

但是,如果您真的想成为“幻想”,该怎么办呢:不测试所有数字,而直接在O(1)中得到结果:

res = r - (r % d) if (r - (r % d) >= l) else -1

(这里不需要所有括号,但是恕我直言使它更具可读性,所以这甚至可以满足您的部分要求。)


从您的评论看来,您似乎正在尝试"Code Golf",目的是拥有尽可能短的代码。在这种情况下,您可以采用第三种方法,但是使用不带三进制... if ... else ...的此变体。这也完全符合您的“不必要和不可读”的要求:

x=[r-r%d,-1][r-r%d<l]  # for code-golf only!

我不会告诉您它是如何工作的,但是,您必须自己找到它。


1)除非这是某种混淆代码挑战,否则可能。