python - 有效地循环遍历一对列表来比较元素
问题描述
我有 2 个清单。其中之一是列表列表。进一步来说:
lst1 = [[4, 5, 6], [19, 20, 24, 25]]
lst2 = [8, 21]
每个列表列表的数字代表索引。
我想要做的是删除lst2
不在每个列表的索引之间的任何元素lst1
。
例如,数字8 fromlst2
应该被删除,因为它不在 的两个列表(元素)的第一个和最后一个数字之间lst1
。不应删除数字 21,因为它位于 的第二个列表(元素)的第一个和最后一个元素之间lst2
。
到目前为止我写的代码是:
for elem2 in lst2:
count = 0
for elem1 in lst1:
minsubelem = min(elem1)
maxsubelem = max(elem1)
condition = not ((elem2 > minsubelem) and (elem2 < maxsubelem))
if condition:
count += 1
if count == len(lst1):
index = lst2.index(elem2)
lst2.pop(index)
print(lst2)
返回:
[21]
这可行,但正如您可以想象的那样,使用 2 个 for 循环并不是最优的,如果列表很长,计算时间可能会显着增加。
为了提高效率,该代码的潜在替代品应该是什么?
说明:
- 中的索引
lst2
永远不等于中的任何索引lst1
。 - 我已经阅读了itertools文档,但可能我缺乏将建议的方法链接到我的用例的经验。
解决方案
如果您保证对其中的子列表lst1
进行排序,则无需查找每个子列表的最小值和最大值。只需抓住每个子列表的第一个和最后一个元素,并将它们用作您的最小值和最大值。此外,一般来说,保留所需元素而不是清除不想要的元素要容易和干净得多 - 而不是弹出你不想要的元素,只需构建一个新列表,只保留你想要的那些元素:
lst1 = [[4, 5, 6], [19, 20, 24, 25]]
lst2 = [8, 21]
def predicate(value):
return any(l[0] < value < l[-1] for l in lst1)
print(list(filter(predicate, lst2)))
输出:
[21]
>>>
编辑 - 为了解决您无法使用的问题filter
(因为您需要将您的lst1
作为参数传递给predicate
),您可以使用functools.partial
:
from functools import partial
lst1 = [[4, 5, 6], [19, 20, 24, 25]]
lst2 = [8, 21]
def predicate(value, ranges):
return any(l[0] < value < l[-1] for l in ranges)
print(list(filter(partial(predicate, ranges=lst1), lst2)))
注意,最后这仍然基本上等同于使用两个循环。一个“循环”遍历 中的所有项目lst2
,对每个项目调用谓词,另一个循环遍历lst1
(调用ranges
in predicate
)中的每个子列表。不过,由于发生在any
.
推荐阅读
- c++ - 或者合并列表
- c# - 无法在 ASP .NET MVC 中设置通过模型传递的 jQuery 生成的下拉列表选定值
- python - SyntaxError:在将文本转换为元组列表时在 ast.py 中解析时出现意外 EOF
- r - 使用磅“#”加 pch 15 的图例
- tensorflow - 了解 LSTM 预测模型中的时期、批量大小、准确性和性能增益
- python - 运行 Poetry install 命令给出错误:列表索引超出范围
- c++ - 如何使用操作符<
1)
我想在运算符中进行重载,<<
以便可以打印模板 T 的矩阵。我想使用
<<
模板类的运算符并使其对齐,我必须知道写入的字符数并在最后添加空格,直到达到一定数量的字符。但是,我不知道如何(如果可以)获取写入的字符串或写入的字符数......<
- python - 如何在不使用循环的情况下删除相邻的重复值?
- azure - Sql Azure 故障转移组中复制滞后的 SLA 是什么?
- android - 如何将程序降级到较低的android版本?