Python 每层放置pow(N,层)元素
给你一张单子Python 每层放置pow(N,层)元素,python,Python,给你一张单子 L=[6,3,87,90,90,90,43,21,1] 我正在创建一个有点像树的结构,其中每个级别在一个数组中存储pow(2,级别)元素 这是我试过的代码 from collections import defaultdict def slotify(L): level = defaultdict(dict) ptr = 0 try: for ref in xrange(len(L)): #print ref
L=[6,3,87,90,90,90,43,21,1]
我正在创建一个有点像树的结构,其中每个级别在一个数组中存储pow(2,级别)元素
这是我试过的代码
from collections import defaultdict
def slotify(L):
level = defaultdict(dict)
ptr = 0
try:
for ref in xrange(len(L)):
#print ref
for count in xrange(pow(2,ref)):
level[ref].update({ptr:L[ptr]})
ptr += 1
except (IndexError) as e:
return level
slotify(L)
Out[297]: defaultdict(<type 'dict'>, {0: {0: 6}, 1: {1: 3, 2: 87}, 2: {3: 90, 4: 90, 5: 90, 6: 43}, 3: {8: 1, 7: 21}})
从集合导入defaultdict
def润滑油(L):
级别=默认dict(dict)
ptr=0
尝试:
对于X范围内的ref(透镜(L)):
#打印参考
对于X范围内的计数(功率(2,参考)):
级别[ref]。更新({ptr:L[ptr]})
ptr+=1
除(索引器)外,如e:
返回水平
slotify(L)
Out[297]:defaultdict(,{0:{0:6},1:{1:3,2:87},2:{3:90,4:90,5:90,6:43},3:{8:1,7:21})
输出是正确的
我想知道一个更好的逻辑实现,更好的代码。谢谢。以下是我应该怎么做的:
def slotify(L):
level = []
counter = 1
while counter*2 <= len(L):
level.append(L[counter-1:counter*2-1])
counter = counter * 2
level.append(L[counter-1:])
return level
到
因为python处理事情的方式
为了获得更高的性能,您可以将append替换为+=[](参见注释,另一个由user2290820提供的注释)
如果缓存len(L)的返回值,速度会更快,因为只需计算一次,就不必再担心全局查找
以下是目前的代码:
def slotify(L):
level=[]
counter=1
counter2=2
val=len(L)
while counter2<=val:
level+=[L[counter-1:counter2-1]]
counter=counter2
counter2+=counter2
level+=[L[counter-1:]]
return level
def slotify(L):
级别=[]
计数器=1
计数器2=2
val=len(L)
虽然counter2如果列表如评论中所述是正确的,我会首先尝试以下内容。下面是一个性能更高的答案
In [1]: from math import *
In [2]: L = [6,3,87,90,90,90,43,21,1]
In [3]: a=L[:] # make a copy that gets trashed
In [4]: [[a.pop(0) for k in range(min(len(a),2**k1))] for k1 in range(int(log(len(a),2))+1)]
Out[4]: [[6], [3, 87], [90, 90, 90, 43], [21, 1]]
要获得更高的性能(速度超过3倍):
[2]中的L=[6,3,87,90,90,90,43,21,1]
在[3]中:def润滑油(L):
返回[L][(1)为什么你想让它成为每一级的词典?为什么不只是一个列表?@thefourthey刚刚再次更正了逻辑;当然它可以是一个列表。如果我可以问的话,为什么不可以是一个dict?为什么词典是一个更好的问题?你没有删除任何东西,所以在所有情况下,列表上的操作都比词典快,或者说同样快。你应该试试看在上,虽然它只适合一行(这总是很酷),但速度非常慢。它甚至比OP的解决方案还要慢。在使用cProfile(Linux上的Python 2.7.5)分析的10次运行中,L有5*10**7值。它在我的代码和你的代码之间以毫秒的速度切换(虽然它更经常在你这边,但不在5%sd之内)您甚至可以进一步减少函数=>level+=[L[counter-1:counter\u n2-1]]和level+=[L[counter-1:]]在ipython中显示4个func调用
counter_n2 += counter_n2
def slotify(L):
level=[]
counter=1
counter2=2
val=len(L)
while counter2<=val:
level+=[L[counter-1:counter2-1]]
counter=counter2
counter2+=counter2
level+=[L[counter-1:]]
return level
In [1]: from math import *
In [2]: L = [6,3,87,90,90,90,43,21,1]
In [3]: a=L[:] # make a copy that gets trashed
In [4]: [[a.pop(0) for k in range(min(len(a),2**k1))] for k1 in range(int(log(len(a),2))+1)]
Out[4]: [[6], [3, 87], [90, 90, 90, 43], [21, 1]]
In [2]: L = [6,3,87,90,90,90,43,21,1]
In [3]: def slotify(L):
return [L[(1<<k)-1:(1<<(k+1))-1] for k in range(len(L).bit_length())]
In [4]: slotify(L)
Out[4]: [[6], [3, 87], [90, 90, 90, 43], [21, 1]]