我正在使用Visual Studio代码1.39.1在ubuntu 19.04上运行python 3.7.3。我有点菜鸟,请耐心等待。
我正在使用Python进行计算和编程。作者给出了我输入VSC的这个示例,我对99%的准确率表示肯定,但是它没有执行程序应做的工作,即找到两个列表的交集:
def intersect(L1,L2):
tmp = []
for e1 in L1:
for e2 in L2:
if e1 == e2:
tmp.append(e1)
break
result = []
for e in tmp:
if e not in result:
result.append(e)
return result
S = [2,3]
T = [2,3,4]
intersect(S,T)
输出为[2]
而不是[2,3]
,因此该程序似乎未通过S
运行,但我不知道为什么。
谢谢。
答案 0 :(得分:3)
Python使用缩进来标记代码块的开始和结束,例如函数或循环体:
for condition:
statement_in_loop()
statement_in_loop()
statement_outside_of_loop()
如果要缩进最后一行,它将在循环内。某些语言使用花括号标记循环的主体,而Python则不。
在复制/粘贴代码时要特别小心。通常,编辑者会尝试帮助您为您的缩进进行修复,并最终改变逻辑。
您的代码似乎过度缩进了最终循环,这使它运行了太多次。
尝试一下:
def intersect(L1,L2):
tmp = []
for e1 in L1:
for e2 in L2:
if e1 == e2:
tmp.append(e1)
break
result = []
for e in tmp:
if e not in result:
result.append(e)
return result
S = [2,3]
T = [2,3,4]
intersect(S,T)
答案 1 :(得分:1)
现在,Adam为您提供了一个可行的解决方案,关于您的算法效率也有很多话要说。请注意,这将超出您问题的范围。
请注意,对于第一个列表中的每个元素,都会对第二个列表中的每个元素进行检查。这意味着,如果两个列表都具有n个元素,则至少要进行n ^ 2个比较。假设n变大,例如100000,并且元素可能出现的大小范围足够大,您的算法将能够处理这个问题?通常,如果可能的话,您要尽量避免嵌套for循环。在这种情况下是:
让我们从导入一个为我们提供随机数的工具开始,因为我太懒了,无法手工生成100000个数字:
from random import randrange as rr
现在让我们设置一些高参数来测试算法:
list_length = 10000
random_space = 200000
让我们使用以下参数创建两个列表:
l1 = [rr(0,random_space,1) for i in range(list_length)]
l2 = [rr(0,random_space,1) for i in range(list_length)]
现在这是您正确缩进的算法,其中添加了一个变量checks
,可以大致告诉我们比较两个元素的次数:
def intersect(L1,L2):
tmp = []
checks = 0
for e1 in L1:
for e2 in L2:
checks += 1
if e1 == e2:
tmp.append(e1)
break
result = []
for e in tmp:
if e not in result:
result.append(e)
return result, checks
让我们打印出结果:
res, checks = intersect(l1, l2)
print(res)
print("Number of comparisons: "+str(checks))
现在运行代码。我认为您会发现一切正常,但是这需要一些时间,比较次数可能接近1亿!尝试将list_length
从10000
更改为100000
,当您现在运行代码时,代码是否还会完成?
现在让我们进行一些更改。我们删除最后三行。然后我们介绍交叉函数的修改版本:
def intersect_v2(L1, L2):
dict = {}
checks = 0
for e1 in L1:
checks += 1
dict[e1] = 1
for e2 in L2:
checks += 1
if e2 in dict:
dict[e2] += 1
return [e for e in dict if dict[e] > 1], checks
请注意,我们在这里只浏览每个列表一次。这有多大的不同?
让我们测试一下。将list_length
改回10000
。然后使用修改后的intersect函数将最后三行添加回去:
res, checks = intersect_v2(l1, l2)
print(res)
print("Number of comparisons: "+str(checks))
运行代码,然后查看。然后尝试将list_length
改回100000
并再次运行。现在是否在合理的时间内完成?
也许有更有效的方法可以做到这一点。但是,摆脱嵌套的for循环通常很重要。