给出一个清单
L = [6,3,87,90,90,90,43,21,1]
我正在创建一个类似树的结构,其中每个级别将pow(2,level)元素存储在数组
中这是我试过的代码
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}})
输出正确。
我想知道更好的逻辑实现,这个逻辑的代码要好一些。感谢。
答案 0 :(得分:2)
我将如何做到这一点:
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
这循环遍历关卡并将它们插入“级别”,除了最后一级,它只是添加其余几个,因为它可能不一定是一个完整的级别。
你甚至可以更进一步,并缓存计数器* 2值以保存乘法(改编自用户建议2290820)
def slotify(L):
level = []
counter = 1
counter_n2 = 2
while counter_n2 <= len(L):
level.append(L[counter-1:counter_n2-1])
counter = counter_n2
counter_n2 = counter_n2 * 2
level.append(L[counter-1:])
return level
你甚至可以进一步改变
counter_n2 = counter_n2 * 2
到
counter_n2 += counter_n2
因为python处理事物的方式。
并且为了获得更高的性能,您可以使用+ = []替换附加内容(请参阅注释,另一个用户2290820)
如果你从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
你不会比这快得多。
程序流程与第一个程序流程相同。
但我要归功于rickhg12hs。我的代码比他的速度快(目前几乎没有,我确定他可以再次推动我的过去;))我的设置(2.7.5与Linux),但他的代码比我的更好。 (我现在看起来有点像c程序)
答案 1 :(得分:1)
如果评论中提到的列表没问题,这是我首先尝试的内容。下面有更高性能的答案。
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倍):
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]]