Python嵌套用于循环数组比较 - 优化的可能性?

use*_*751 1 python arrays

我正在尝试优化嵌套的for循环,将数组中的元素与数组中的其余元素进行比较.

有两部分,第一部分是例如,一个数组有3个元素,每个元素都是一个字典:

[{"someKey_1":"a"}, {"someKey_1":"b"}, {"somekey_1":"a"}]


第一次迭代(第一个元素与第二个元素比较):

测试两个元素的"someKey"键,因为a!= b,那么我们什么都不做


第2次迭代(第1个元素与第3个元素比较):

测试两个元素的"someKey"键,因为a == a,我们做一些逻辑


代码:

for idx, val in enumerate(set_of_pk_values):
    for idx_2, val_2 in enumerate(set_of_pk_values):
        if (val['someKey'] == val_2['someKey'] and idx != idx_2):
                #Some Logic
Run Code Online (Sandbox Code Playgroud)

第二部分与上一个例子(列表中的3个项目)非常相似,在同一个字典中,我们有一个与一个键相关联的数组(现在有一个字典,在数组的每个元素中都有两个键),让我们说:

[{"someKey_1":[b,f]}{"someKey_2":a}, 
{"someKey_1":[e,f]}{"someKey_2":b}, 
{"somekey_1":[h,k]}{"someKey_2":c}]
Run Code Online (Sandbox Code Playgroud)

第一次迭代(第一个元素与第二个元素比较):

使用键遍历数组:someKey_1

b==b (第二个元素是someKey_2),然后做一些逻辑

f!=b (第二个元素是someKey_2),没有逻辑完成


第二次迭代(第一个元素与第三个元素比较):

使用键遍历数组:someKey_1

b==c (第三个元素是someKey_2),然后做一些逻辑

f!=c (第3个元素是someKey_2),没有逻辑完成


代码:

for idx, val in enumerate(set_of_pk_values):
    for idx_2, val_2 in enumerate(set_of_pk_values):
        for pred in val['someKey_1']:
            if(val_2['someKey_2'] == pred):
                #Some Logic
Run Code Online (Sandbox Code Playgroud)

目前第一个嵌套循环的运行时间:21秒,第二个嵌套循环约为19秒.与其他过程相比,1-2秒不等,这部分显然是一个瓶颈.

任何人都可以指出我如何优化这段简单但非常耗时的代码的正确方向?

Art*_*are 5

首先,我相信这应该发布在CodeReview上,而不是StackOverflow.

StackOverflow用于获取无效代码的帮助.
CodeReview用于获取有效的代码的帮助,但您希望使其更好.

其次,这里有一些关于优化它的建议:

  • 不要enumerate()在循环内.
  • 在第一个场景中使用切片以避免无意义的比较.

以下是我将如何重写您的第一个场景:

# Check if two dictionary with the key 'predecessor' are the same,
# and they are NOT the same index (otherwise it would be comparing themselves)
# set_of_pk_values is an array of dictionaries.
for idx, val in enumerate(set_of_pk_values):
    for val_2 in set_of_pk_values[idx+1:]:  # Note the slice and lack of enumerate
        if (val['predecessor'] == val_2['predecessor']):  # Don't waste time checking indexes
            # Do Something Here, also we don't want to compare itself, because it will be true
Run Code Online (Sandbox Code Playgroud)

而不是for\if,使用if in:

for idx, val in enumerate(set_of_pk_values):
    if val in set_of_pk_values[idx+1:]:
        # Do Something Here, also we don't want to compare itself, because it will be true.
Run Code Online (Sandbox Code Playgroud)

如果你真的想要枚举,因为你只需要多次相同的枚举,我只需要在循环外执行一次并将其存储在变量中,然后循环它.这就是我的意思:

我不对,下面不起作用,请参阅评论.

# Doesn't work, see comments.
# from itertools import islice
# whatIEnumerate = enumerate(set_of_pk_values)
# for idx, val in whatIEnumerate:
    # for idx_2, val_2 in islice(whatIEnumerate, idx+1, None):
        # ...
Run Code Online (Sandbox Code Playgroud)