当一个嵌套for循环的范围达到外部for循环的当前迭代时,如何避免多个嵌套for循环?例如,请考虑以下代码:
该程序从列表arr返回一个三元组,arr[i] - arr[j] = arr[j] - arr[k] = d
和i<j<k
。
d =3
arr = [1, 2, 4, 5, 7, 8, 10]
list1 = []
for biggest in range(0, len(arr)):
for bigger in range(0, biggest):
for big in range(0, bigger):
if abs(arr[big] - arr[bigger]) == d and abs(arr[bigger] - arr[biggest]) == d:
list1.append([arr[big], arr[bigger], arr[biggest]])
print(list1))
使用多个嵌套循环还有其他选择吗?
答案 0 :(得分:3)
您可以用以下内容替换三个循环:
from itertools import combinations
for big, bigger, biggest in combinations(range(0, len(arr)), 3):
您可以将所有代码替换为:
print([t for t in combinations(arr, 3)
if t[2] - t[1] == t[1] - t[0] == d])
答案 1 :(得分:2)
您可以使用the combinations function from itertools。您的代码将变为:
from itertools import combinations
d = 3
arr = [1, 2, 4, 5, 7, 8, 10]
list1 = []
for big, bigger, biggest in combinations(arr, 3):
if abs(big - bigger) == d and abs(bigger - biggest) == d:
list1.append([big, bigger, biggest])
print(list1)
它提供与您的代码相同的打印输出(在您删除最后一行的无关右括号后):
[[1, 4, 7], [2, 5, 8], [4, 7, 10]]
请注意,我将变量big
,bigger
,biggest
的含义更改为数组值而不是其索引。使用值和避免索引更加诡计多端,更容易理解。
你也可以在列表理解中做到这一点,看起来略有不同,避免临时列表,以及可能的速度增加。
from itertools import combinations
d = 3
arr = [1, 2, 4, 5, 7, 8, 10]
print([[big, bigger, biggest]
for big, bigger, biggest in combinations(arr, 3)
if abs(big - bigger) == d and abs(bigger - biggest) == d
])
答案 2 :(得分:0)
虽然之前的答案是pythonic,
如果您关心搜索算法的实现,可以通过实现二进制搜索算法在O(N^2logN)
之间找到k
,从而将算法的复杂性从j+1
降低到lst
1}}以及满足d - abs(lst[j] - lst[k]) == 0
的{{1}}的长度。
d = 3
lst = [1, 2, 4, 5, 7, 8, 10]
def bsearch(lst, left, right, j):
while left < right:
k = (left + right) // 2
diff = d - abs(lst[j] - lst[k])
if diff == 0:
return k
if diff > 0:
left = k + 1
else:
right = k
return None
l, result = len(lst), []
for i in range(l):
for j in range(i + 1, l):
diff = d - abs(lst[i] - lst[j])
if diff != 0: continue
k = bsearch(lst, j + 1, l, j)
if not k: continue
result.append((lst[i], lst[j], lst[k]))
print(result)
[(1, 4, 7), (2, 5, 8), (4, 7, 10)]
答案 3 :(得分:0)
我发现更好的方法!避免嵌套循环。
arr = [1,2,3,4,5,6,7,8,9]
d = 3
list1 = arr
list2 = []
for each in (0,len(list1)):
if list1[each] + d in arr and list1[each] + 2*d in arr:
list2.append([list1[each], list1[each]+d, list1[each]+2*d])
print(list2)