代码如下:
reduce(lambda x, (y, z): x | (z << y),
enumerate(map(lambda i: 0 if i < avg else 1, im.getdata())),
0)
令我困惑的是reduce()
lambda x, (y, z): x | (z << y)
我得到了其他两个论点的含义:
enumerate(map(lambda i: 0 if i < avg else 1, im.getdata())),
0
此外,我知道lambda表达式(reduce()
的第一个参数)是将位序列(0或1)转换为整数。我们似乎应该一次按位进行一次右移,但这里是y
,那是什么?
PS:我的问题不是lambda表达式本身,而是它如何与
序列一起工作enumerate(map(lambda i: 0 if i < avg else 1, im.getdata()))
返回
答案 0 :(得分:1)
y
是商品的索引。z
是来自iterable的当前项目。x
是到目前为止的结果(初始值为0)。 x, (y, z)
正在利用元组参数解包(supported in Python 2 only),你也可以把它写成:
x = 0
for y, ind_item in enumerate(map(lambda i: 0 if i < avg else 1, im.getdata()):
x |= (z << y)
Tuple参数解压缩:
>>> def func(x, (y, z)):
print x, y, z
...
>>> func(0, (10, 20))
0 10 20
请注意,此功能已在Python 3中删除,PEP-3113建议执行以下操作:
def func(x, y_z):
y, z = y_z
print x, y, z
...
>>> func(0, (10, 20))
0 10 20
由于lambda
不允许赋值语句,您可以使用索引来获取y
和z
的值:
from functools import reduce
reduce(lambda x, y_z: x | (y_z[1] << y_z[0]),
enumerate(map(lambda i: 0 if i < avg else 1, im.getdata())),
0)
答案 1 :(得分:0)
签名为functools.reduce(function, iterable[, initializer])
。来自doc:
将
function
两个参数累加到sequence
的项目,从左到右,以便将序列缩减为单个值。
这转换为:
lambda x, (y, z): x | (z << y)
enumerate(map(lambda i: 0 if i < avg else 1, im.getdata()))
由于你的lambda
是一个“两个参数”的函数,可以应用于enumerate
的项目,所以一切都很好。
修改强>
enumerate
返回元组列表:
[(0, 'Spring'), (1, 'Summer'), (2, 'Fall'), (3, 'Winter')]
答案 2 :(得分:0)
整个语句只是将数据图像转换为一系列位,然后将这些位打包成单个int。
更好,更易读的方法可能就是这样做。
import array
import numpy
pixel_data = numpy.array(data)
truth_values = pixel_data >= avg
byte_values = numpy.packbits(numpy.array(truth_values, dtype=int))
bit_string = array.array('B', byte_values).tobytes()
bit_int = int.from_bytes(bit_string, byteorder='big')
答案 3 :(得分:0)
有点晚了,
但是这里是相同的代码而不使用嵌套函数和lambdas:
class Img:
def __init__(self, data):
self.data = data
def getdata(self):
return self.data
def function1(i):
if i < avg:
print "function1(%i) == 0"%i
return 0
else:
print "function1(%i) == 1" % i
return 1
def function2(y,z):
print "function2(%i,%i) == %i"%(y,z,z << y)
return z << y
avg = 0
im = Img(list(range(-5,5)))
MAP = map(function1,im.getdata())
print "\nMAP of function1 with im.getdata() == %s"%MAP
ENUM = list(enumerate(MAP))
print "\nENUM of MAP == %s\n"%ENUM
a = 0
for y, z in ENUM:
print "a == %i"%a
value = function2(y,z)
print "a += %i"%(value)
a += value
print "\nResult is\na == %i"%a
输出:
function1(-5) == 0
function1(-4) == 0
function1(-3) == 0
function1(-2) == 0
function1(-1) == 0
function1(0) == 1
function1(1) == 1
function1(2) == 1
function1(3) == 1
function1(4) == 1
MAP of function1 with im.getdata() == [0, 0, 0, 0, 0, 1, 1, 1, 1, 1]
ENUM of MAP == [(0, 0), (1, 0), (2, 0), (3, 0), (4, 0), (5, 1), (6, 1), (7, 1), (8, 1), (9, 1)]
a == 0
function2(0,0) == 0
a += 0
a == 0
function2(1,0) == 0
a += 0
a == 0
function2(2,0) == 0
a += 0
a == 0
function2(3,0) == 0
a += 0
a == 0
function2(4,0) == 0
a += 0
a == 0
function2(5,1) == 32
a += 32
a == 32
function2(6,1) == 64
a += 64
a == 96
function2(7,1) == 128
a += 128
a == 224
function2(8,1) == 256
a += 256
a == 480
function2(9,1) == 512
a += 512
Result is
a == 992