python - 从列表中删除每个第 n 个元素的更好方法
问题描述
我有一个包含 1000 个元素的列表。现在我需要从该列表中删除第 1、第 2、第 4、第 8、第 16、第 32 等元素。这是我的解决方案
i = 0
while pow(2,i) < len(arr):
del arr[pow(2,i) - 1 - i]
i += 1
但我认为这似乎是一些糟糕的代码。有没有更优雅的方法来获得相同的结果?
解决方案
你需要反转你的迭代;从最高值向下删除权力。从大于列表长度的二的次幂开始,然后从那里向下移动:
i = 2 ** len(arr).bit_length() # next higher power-of-two > len
while i > 1:
i >>= 1
del arr[i - 1] # 4th index is 3, 8th index is 7, etc.
另一种选择:您可以生成一个新列表,而不是就地从列表中删除:
[v for i, v in enumerate(arr, 1) if i & (i - 1)]
这使用了一个事实,即 2 的幂只有一个位集;如果你用数字 - 1 掩盖它,你得到零。
演示:
>>> arr = list(range(1, 33)) # 6 values to remove, 1, 2, 4, 8, 16 and 32
>>> arr
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32]
>>> len(arr)
32
>>> [v for i, v in enumerate(arr, 1) if i & (i - 1)]
[3, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31]
>>> i = 2 ** len(arr).bit_length() # highest power-of-two >= len
>>> while i > 1:
... i >>= 1
... del arr[i - 1] # 4th index is 3, 8th index is 7, etc.
...
>>> arr
[3, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31]
>>> arr == [v for i, v in enumerate(range(1, 33), 1) if i & (i - 1)]
True
>>> len(arr)
26
推荐阅读
- graphql - Gatsby 组件中的多个查询
- git - 保存每次运行的 rmarkdown 文件以供记录
- html - 无法使用 fullcalendar 将日历的大小占据所有宽度
- html - HTML页面无法向下滚动并且内容隐藏在页脚后面
- python - 如何从创建日期 Django 开始正好 30 秒
- networking - nftables - 丢弃特定网桥上的 arp 流量
- java - 我可以使用方法名称来创建 Spring JPA 更新查询吗?
- python - 模块“keras.backend”没有属性“unique_object_name”
- kubernetes - 将 Prometheus 部署到不同的 Kubernetes 集群
- python - Pandas 追加速度非常慢,使用 from_dict 时出现问题