【问题标题】:Remove items at positions 1,2,4,8,16,.. from list从列表中删除位置 1,2,4,8,16,.. 的项目
【发布时间】:2015-02-02 23:10:28
【问题描述】:

如何删除列表中索引为 2^x 的每个元素? 我尝试使用一个 for 循环,其中一个代表 x 的变量在每个循环中增加 1,但这会引发超出范围的错误。

例如:

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

【问题讨论】:

  • 仅在 2^x 小于列表长度时才将其删除 ....
  • 等等,在您的示例输出中,您使用的是基于 1 的索引,而不是 Python 默认的基于 0 的索引吗?
  • 您可能必须向后循环,否则所有较高元素的位置都会发生变化。
  • 在索引 0,1,3,7,.. 然后
  • 从技术上讲,0 不是 2 的幂...

标签: python list python-3.x indexing


【解决方案1】:

在这里使用众所周知的“检查x 是否为2 的幂”位操作技巧——(x & (x - 1)) == 0 是一个不可抗拒的诱惑。

因为这里你实际上想要检查x + 1,而在 Python 中 == 0 可以包含在隐式真实性检查中......:

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

太不可思议了,唉...!-)

嗯,至少很容易检查它是否有效...:=_

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

【讨论】:

    【解决方案2】:

    可能不是最有效的解决方案,但这很好而且简单:

    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]
    

    【讨论】:

    • 这让我很沮丧,因为 Python 列表推导没有任何形式的 while/until 支持。 itertools.takewhile 和朋友们只是不会自然地与通常的(通常不基于lambda)Pythonic 习语混合。
    • @JohnKugelman,谢谢,我知道列表查找会使这非常低效,应该考虑使用集合。
    【解决方案3】:

    这就是我的做法:

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

    这会产生[1, 0, 1, 0, 1]

    【讨论】:

    • 你颠倒了想要的结果。
    【解决方案4】:

    分析方法:

    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]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-07-05
      • 2022-12-20
      • 2019-07-06
      • 2016-05-08
      • 2011-03-18
      • 1970-01-01
      • 2018-05-30
      相关资源
      最近更新 更多