我能以某种方式将此循环转换为地图(lambda x:..))吗?

时间:2016-06-30 19:38:07

标签: python optimization lambda

我正在尝试优化一种方法,该方法计算1

中每个数字的二进制表示中0 -> num的数量
# Example of how the below works, for clarity
#
# base => [0,1,1,2,1,2,2]
# index => 7
#
#   {7} --
#       bin(7)              :   111
#       bin(7-1)            :   110
#       111 & 110           :   110 (6)
#       append(base[6]+1)   :   append(3)
#     //end 7
#
# base => [0,1,1,2,1,2,2,3]

def countBits(num):
    index = 1
    base = [0]

    while(index <= num):
        base.append(base[(index & (index - 1))]+1)
        index += 1

    return base

我想知道是否有一种方法可以将while循环转换为可以在适当位置而不是循环的东西?我的第一个想法是做一些像......

base.append(map(lambda index: base[(index & (index -1))]+1, num))

但这根本没有做任何事情。base保持不变。我假设我只是不完全理解map(lambda x:...)语法的作用。我只使用了几次,直接拨打列表。

2 个答案:

答案 0 :(得分:0)

我发现了2种(功能样式)解决方案,但它们很难“到位”。而且,可能两者都会慢慢循环。

首先不是使用map而是使用reduce:

def countBits2(num):
    from functools import reduce
    index = 1;
    base = reduce( lambda base, index: (base.append( base[(index & (index - 1))]+1 ), base)[1], range( 1, num+1 ), [0] )
    return base

第二张地图:

def countBits3( num ):
    base = [0]     
    def m_append( index ):
        val = base[(index & (index - 1))]+1
        base.append( val )
        return val

    return [0] + list( map( m_append, range( 1, num+1) ) )
    #also possible to return base
    #list( map( ... ) ) # list required to force mapping on py3
    #return base

m_append可以重写为lambda(与reduce尝试相同)但是它将是非常长的lambda。

答案 1 :(得分:0)

也许你想要这样的东西?

num = 11

base = [0]
for _ in range(1, num):
    base.extend(map(lambda index: base[(index & (index -1))] + 1, [_]))

结果:

[0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2]