每级放置pow(N,level)元素

时间:2013-11-17 14:07:09

标签: python

给出一个清单 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}})

输出正确。

我想知道更好的逻辑实现,这个逻辑的代码要好一些。感谢。

2 个答案:

答案 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]]