Lambda Range for Loop

时间:2015-12-11 01:53:37

标签: python python-2.7 for-loop lambda

注意:我不确定我是否应该在这里或CodeGolf上提出这个问题,所以如果合适,我会在这里发帖。

我正在尝试使用遵循以下格式的lambdas在python中创建一个for循环:

x = 10
y = range(10)
w = 2

for g in range(w*w, x, w):
    y[g] = 0

print y

这会输出正确的列表[0, 1, 2, 3, 0, 5, 0, 7, 0, 9]。但是,我无法通过使用lambdas来更改列表。我的代码是这样的:

print(lambda w,x=10,y=range(10): (map(lambda g: (lambda f=y.__setitem__: (f(g,0) )()), range(w*w,x,w)), y))(2)

"""
w is the step value in the for loop, which is 2
x is the size of the list, 10
y is the list, range(10)

lambda g is the first argument for map as the function. It sets the value of the list y at the current index g to be 0, through the use of lambda f's setitem
range(w*w,x,w) is the second argument passed to map as an iterable. In theory, all the indexes of y in this list should be set to 0 through the use of lambda f

y is returned to be printed
2 is the value passed to w
"""

然而,这会返回错误的[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]。有谁知道如何在一条线上实现这一目标?我应该使用其他内置函数来创建lambda中的循环吗?我使用thisthis作为参考,以防万一。

3 个答案:

答案 0 :(得分:2)

可能更容易使用列表推导:

print (lambda w, x=10, y=range(10):\
       [(0 if (i >= w*w and i < x and i%w==0) else n) for i, n in enumerate(y)])(2)

为了便于阅读,已移至两行,但您可以删除\和换行符,它将正常运行。

有一点需要注意,这并不会改变原始列表,但会返回一个新列表。

如果您需要更新原始列表并将其返回,则可以使用短路:

print (lambda w, x=10, y=range(10):\
       ([y.__setitem__(i, 0) for i in range(w*w, x, w)] and y))(2)

校正:

上述代码仅在range(w*w, x, w)非空时才有效,即w*w > x,这是一个弱条件。

以下是此问题的更正:

print (lambda w, x=10, y=range(10):\
       (([y.__setitem__(i, 0) for i in range(w*w, x, w)] or 1) and y))(2)

这使用(a or 1) and b在评估b的值后始终评估为a的事实。

答案 1 :(得分:1)

使用map因其副作用而感到憎恶,但是:

>>> x = 10
>>> y = range(10)
>>> w = 2
>>> map(lambda i: y.__setitem__(i, 0), range(w*w, x, w))
[None, None, None]
>>> y
[0, 1, 2, 3, 0, 5, 0, 7, 0, 9]

一种不太令人反感的方法是使用切片分配

>>> y = range(10)
>>> y[w*w: x: w] = [0]*len(range(w*w, x, w))
>>> y
[0, 1, 2, 3, 0, 5, 0, 7, 0, 9]

答案 2 :(得分:1)

这是一个纯lambda实现,它将wxy作为顶级lambda的参数:

>>> (lambda w,x,y: (lambda s: map(lambda v: 0 if v in s else v, y))(set(range(w*w,x,w))))(2,10,range(10))
[0, 1, 2, 3, 0, 5, 0, 7, 0, 9]
>>> 

请注意,这样可以避免使用__setitem__