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