来自 True 值范围(开始和结束)的布尔列表,不使用 for 循环

Posted

技术标签:

【中文标题】来自 True 值范围(开始和结束)的布尔列表,不使用 for 循环【英文标题】:A boolean list from ranges of True values (start and end), without using a for loop 【发布时间】:2021-11-26 04:18:20 【问题描述】:

例如,我有这个包含范围的列表。

x=[[1,4],
   [6,7],
   [9,9]]

其中每个项目的第一个值(例如[1,4])是开始位置(1),第二个值是结束(4)位置。

我想将此范围列表转换为布尔列表,其中如果位置位于上面列表中指示的(任何)范围(即开始和结束位置)之间,则值为True,否则值应该是False

[False, True, True, True, True, False, True, True, False, True]

这显然可以使用 for 循环来实现。但是,我正在寻找其他单行选项。理想情况下,我正在寻找一些也适用于熊猫系列的方法。

注意:这本质上是这个问题的相反问题:Get ranges of True values (start and end) in a boolean list (without using a for loop)

【问题讨论】:

确定映射到True的逻辑是什么?为什么您的布尔列表有 10 个项目,而原始列表有 6 个? @ddejohn 我同意它没有很好的格式或解释,但我想逻辑类似于另一个问题here 【参考方案1】:

使用 numpy 的一种有希望的有效方法:

low, high = np.array(x).T[:,:, None] # rearrange the limits into a 3d array in a convenient shape
a = np.arange(high.max() + 1) # make a range from 0 to 9
print(((a >= low) & (a <= high)).any(axis=0))

在 python 循环中编辑数组的替代方法:

result = np.zeros(np.array(x).max() + 1, dtype=bool)
for start, end in x:
    result[start:end+1] = True

这可能会更快,具体取决于编辑数组切片相对于 numpy 2d 矩阵比较的速度。

【讨论】:

有什么复杂性?我认为 O(max(high) * len(high)),所以相当二次? 也许是矩阵数学大 O 复杂度方面的专家可以发表评论。从某种意义上说,它将所有工作委托给用优化良好的 C 语言编写的 numpy 向量函数,避免任何 python 循环,这是一种高效的方法。如果首先对范围进行排序,或者假定范围已经排序,则可能会有更好的解决方案。 我认为我们不需要“专家”:-)。你的a &gt;= low 是一个二维数组,宽度为 max(high),高度为 len(high),对吧?时间肯定是线性的。该行代码中的其他操作也是如此。 而循环解决方案只需要 O(max(high))。

以上是关于来自 True 值范围(开始和结束)的布尔列表,不使用 for 循环的主要内容,如果未能解决你的问题,请参考以下文章

提供来自 Main 组的子类型列表以及范围编号

AngularJS 布尔值在范围内总是返回 true

因为该组节的条件字段不存在或无效所以无法打印

如果列表包含布尔值,如何从列表中获取整数的索引?

Python中的布尔值列表到整数

逻辑组合布尔值列表的最“pythonic”方式是啥?