Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/xslt/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 双重迭代的替代方案_Python_Iteration - Fatal编程技术网

Python 双重迭代的替代方案

Python 双重迭代的替代方案,python,iteration,Python,Iteration,我有一个程序,要求我将列表中的每个值与同一列表中的每个其他值进行检查。如果我确定了满足某些要求的内容,我会将其添加到另一个列表中,以便在该过程完成后删除 伪代码: for value1 in my_list: for value2 in my_list: if meets_requirements(value1, value2): to_be_removed.append(value2) 我觉得这很难看。变量的命名约定很难指定或理解。有一种可能性

我有一个程序,要求我将列表中的每个值与同一列表中的每个其他值进行检查。如果我确定了满足某些要求的内容,我会将其添加到另一个列表中,以便在该过程完成后删除

伪代码:

for value1 in my_list:
    for value2 in my_list:
        if meets_requirements(value1, value2):
            to_be_removed.append(value2)
我觉得这很难看。变量的命名约定很难指定或理解。有一种可能性(虽然在本例中不太可能),我可能会在迭代列表时意外修改列表。性能可能存在问题

除了执行这些双重迭代,还有更好的替代方案吗?

如果没有,我有什么方法可以让它更具可读性并且“感觉”像是质量代码吗?

您可以在这里使用。虽然这仍然相当于嵌套循环,但可读性更高:

from itertools import product
for value1, value2 in product(my_list, repeat=2):
    if meets_requirements(value1, value2):
        to_be_removed.append(value2)
我会使用一个与
product()
一起使用的:

在@tobias_k的评论之后,如果您不希望在结果中包含相同值的多个实例,并且如果元素的顺序无关紧要,则可以使用:


您不必首先找到删除的值。只需一次性创建所需列表:

my_list = [y for y in my_list 
             if not any(meets_requirement(x,y) for x in my_list)]


查看
itertools
,特别是
产品
组合
您能否澄清
我的列表
是否应该在这两个地方引用相同的列表?或者
value1
value2
是否来自不同的列表?@MarkDickinson-相同的列表涉及什么类型的“需求”?它是否可以用于对列表进行预排序,以减少所需的测试数量?它们是否具有传递性,即满足_要求(值1,值2)是否意味着满足_要求(值2,值1)?你能通过知道value1来计算value2的可能值吗?基本上,我正在识别并删除同一列表中其他字符串的子字符串。如果愿意的话,可以说是一种重复数据消除。唯一需要注意的是,每个字符串都有一个关联的“count”,如果字符串的计数差异太大(delta>10),那么我不会删除它。抱歉这么含糊——保密协议让我不能透露太多。让我知道这是否有帮助<代码>itertools.product是用C实现的,因此不太一样。@siebz0r我刚才说的是大O时间复杂性。:-)与列表理解相比,我认为使用这种方法的优势在于,对于有过程背景的人(其他,未来的开发人员)来说,它更容易理解和使用。此外,如果需要,在比较过程中更容易包含更多逻辑。还有什么其他的好处吗?我觉得列表理解更像python,我想你会发现其他python开发人员认为它更容易理解。不知道这是否是有意的,但是这样删除
可能会有很多
v2
的副本。@tobias\k:你是什么意思?将检查每个可能的对
v1、v2
,如果
满足要求()
返回
True
v2
将添加到列表中,就像在OP的代码中一样。我看不出有什么区别?是的,没有区别;这与OPs代码中的行为相同<对于满足要求的每个
v1
,将添加code>v2
。我只是想知道这种行为在OPs代码中是否是故意的。@tobias_k:说得好。我还添加了一个集合理解示例。虽然它不一定是等效的,但最好从
any()
中删除
[]
,让它短路。如果
符合_要求
没有副作用,则会产生相同的结果。谢谢!我喜欢你的建议。通过对“真实数据”进行一些快速、非科学的测试,我发现使用这种方法比使用
itertools.product
要快得多。我不是在尝试预先优化;只是权衡两种方法的利弊。这是典型的列表理解吗?我应该期望线性行为吗?我猜这是因为使用其他方法itertools.product首先创建(a,b)的每个可能组合的列表,然后测试每个组合。然而,在上面的方法中,any()方法是短路的(正如Steve Jessop所指出的),因此只要它从满足_要求()中找到一个真实值,它就会删除“y”,而无需测试进一步的组合。一般来说,如果你真的需要测试每个组合,我不认为itertools会慢一些,在这种情况下这是不必要的。而且,两种方法都是O(n^2)而不是O(n),因为对于每个元素,你必须针对所有其他元素进行测试。
to_be_removed = {v2 for v1, v2 in product(mylist, repeat=2) 
                               if meets_requirement(v1, v2)}
my_list = [y for y in my_list 
             if not any(meets_requirement(x,y) for x in my_list)]