简体   繁体   English

从列表中删除位置1,2,4,8,16,..的项目

[英]Remove items at positions 1,2,4,8,16,.. from list

How would I go about removing every element with index 2^x in a list? 我将如何删除列表中索引为2 ^ x的每个元素? I've tried using a for loop with a variable representing x increasing by 1 in every loop but this throws the out of range error. 我尝试过使用一个for循环,该循环的变量表示x在每个循环中均增加1,但这会引发超出范围的错误。

eg: 例如:

remove([0,0,1,1,0,1,0,1,1])
>>>[1,0,1,0,1]

It's an irresistible temptation here to use the well-known "check if x is a power of 2" bit-manipulation trick -- (x & (x - 1)) == 0 . 使用众所周知的“检查x是否为2的幂”的位操纵技巧- (x & (x - 1)) == 0是一个不可抗拒的诱惑。

Since here you actually want to check x + 1 , and in Python == 0 can be subsumed in an implicit truthiness check...: 因为这里实际上是要检查x + 1 ,而在Python中== 0可以包含在隐式真实性检查中:

def remove(listarg):
    return [it for x, it in enumerate(listarg) if (x & (x+1))]

Pretty inscrutable, alas...!-) 挺不可思议的,a ...!-)

Ah well, at least it's easy to check it works...:=_ 嗯,至少可以很容易地检查它是否有效...:= _

>>> set(range(1,35)).difference(remove(range(1,35)))
{32, 1, 2, 4, 8, 16}

Probably not the most efficient solution, but this is nice and simple: 可能不是最有效的解决方案,但这很简单:

import math

orig = [0,0,1,1,0,1,0,1,1]

max_power_of_2 = int(math.log(len(orig), 2))
# Only generate these up to the length of the list
powers_of_2 = set(2**n for n in range(max_power_of_2 + 1))

# Your example output implies you're using 1-based indexing,
#   which is why I'm adding 1 to the index here
cleaned = [item for index, item in enumerate(orig) 
           if not index + 1 in powers_of_2]

In [13]: cleaned
Out[13]: [1, 0, 1, 0, 1]

This is how I'd do it: 这是我的方法:

from math import log

my_list  = [0,0,1,1,0,1,0,1,1]
new_list = [item for i,item in enumerate(my_list,1) if not log(i,2).is_integer()]

This yields [1, 0, 1, 0, 1] . 这产生[1, 0, 1, 0, 1] 1,0,1,0,1 [1, 0, 1, 0, 1]

Analytical approach: 分析方法:

from math import ceil, log

def remove(list_):
    """ Create new list with every element with index 2**x removed. """
    indices = set((2**i-1 for i in range(int(ceil(log(len(list_), 2)))+1)))
    return [elem for i, elem in enumerate(list_) if i not in indices]

print(remove([0,0,1,1,0,1,0,1,1]))  # --> [1, 0, 1, 0, 1]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM