lambda x,(y,z)是什么:x | (z<< y)在reduce()中起作用?

时间:2014-12-18 13:06:21

标签: python lambda

代码如下:

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()))

返回

4 个答案:

答案 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不允许赋值语句,您可以使用索引来获取yz的值:

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