Python 我是否可以以某种方式将此循环转换为映射(lambda x:…)?
我正在尝试优化一种方法,该方法在从Python 我是否可以以某种方式将此循环转换为映射(lambda x:…)?,python,optimization,lambda,Python,Optimization,Lambda,我正在尝试优化一种方法,该方法在从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) #
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
#为了清晰起见,下面的示例说明了如何工作
#
#基本=>[0,1,1,2,1,2,2]
#指数=>7
#
# {7} --
#bin(7):111
#垃圾箱(7-1):110
# 111 & 110 : 110 (6)
#追加(基[6]+1):追加(3)
#//完7
#
#基本=>[0,1,1,2,1,2,2,3]
def计数位(num):
索引=1
基数=[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将非常长。我找到了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。也许您想要这样的东西
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]
也许你想要这样的东西
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]
这真的有效吗?是的!刚刚更新了一条注释,解释了一个示例如果循环体引用了您要添加的内容,则很难将循环转换为列表理解或map
表达式。base.append(base[…])
是一个危险信号,你不容易翻译成一行。@MrDuk你可以用map
解决这个问题,但是你不能涉及lambda
,因为map不会修改base
,除非它完全耗尽了它所迭代的内容。map(lambda n:bin(n).count('1'),range(num+1))
这真的有效吗?是的!刚刚更新了一条注释,解释了一个示例如果循环体引用了您要附加的内容,则很难将循环转换为列表理解或映射表达式。base.append(base[…])
是一个危险信号,你不容易翻译成一行。@MrDuk你可以用map
解决这个问题,但是你不能涉及lambda
,因为map不会修改base
,除非它完全耗尽了它所迭代的内容。map(lambda n:bin(n).count('1'),range(num+1))