提问人:Pondo 提问时间:8/15/2023 最后编辑:tobias_kPondo 更新时间:8/15/2023 访问量:52
比较三个列表以过滤掉常见元素
Comparing three lists to filter out common elements
问:
我是python的新手,目前正在练习。 练习题:为爱丽丝提供函数affair_meet,该函数将鲍勃、爱丽丝和西尔维斯特每天在巴黎的路径,并返回一组爱丽丝和西尔维斯特可以见面并确保鲍勃不会出现的所有地点。我已经设法完成了下面的代码,但是,我不确定如何过滤掉鲍勃运动,有人可以给我指出正确的方向吗?
def affair_meet(bob, alice, silvester):
list1 = []
for x in alice:
for c in bob:
for i in silvester:
if x == i and x !=c:
if x not in list1:
list1.append(x)
return(list1)
if __name__ == '__main__':
alice = ['Ⅱ', 'Ⅳ', 'Ⅱ', 'ⅩⅠⅩ', 'ⅩⅤ', 'Ⅳ', 'Ⅲ']
bob = ['Ⅳ', 'Ⅲ', 'Ⅱ', 'ⅩⅩ', 'Ⅱ', 'ⅩⅩ']
silv = ['ⅩVⅢ', 'ⅩⅠⅩ', 'Ⅲ', 'Ⅰ', 'Ⅲ', 'ⅩVⅢ']
print(affair_meet(bob, alice, silvester)
此代码将吐出 [“XIX”,“III”] 显然,我想摆脱“III”,因为鲍勃也会在那里。有什么提示吗?
答:
0赞
Rémi.T
8/15/2023
#1
不需要,你可以在最后检查它,如下所示:for c in bob:
if x == i:
if x not in list1:
if x not in bob:
list1.append(x)
像这样,你确定 bob 不会访问 x。
2赞
tobias_k
8/15/2023
#2
代码的问题在于,你迭代了 和 的所有组合,这意味着如果 Alice 和 Silvester 之间存在匹配项,并且如果 Bob 中有任何位置不匹配,则将在结果列表中添加一个位置。x
c
i
相反,只需使用单个循环并用于检查其他列表。由于顺序并不重要,因此用于消除任何重复项,从而减少另一个 -check。alice
in
set(alice)
if
def affair_meet(bob, alice, silvester):
res = []
for x in set(alice):
if x in silvester and x not in bob:
res.append(x)
return res
您可以使用列表推导式来缩短此时间。请注意,由于每次迭代中都有 O(n) 成员资格测试,这仍然是 O(n²)。
def affair_meet(bob, alice, silvester):
return [x for x in set(alice) if x in silvester and x not in bob]
或者使用基本的集合操作;当您转换时,这也应该更快,并且只转换一次,然后进行快速的 O(1) 查找。如果您确实需要将结果作为列表,请转换回之前。bob
silvester
set
list
return
def affair_meet(bob, alice, silvester):
return set(alice) & set(silvester) - set(bob)
评论
0赞
Bobdabear
8/15/2023
如果您要使用列表推导 imo,则即使示例使用小列表,也无需转换为 a 并产生额外的开销,转换为 0(N),当没有任何收获时,这可能会在生产中受到伤害。您还忘记了 op 的 List1 中没有的 xalice
set
return [x for x in alice if x in silverster and x not in [bob, list1]]
1赞
tobias_k
8/16/2023
@Bobdabear 这不是为了加快速度,而是为了没有必要进行检查。使用 list-comp,您还可以将其设置为 set-comp,而无需转换为 first;这是我首先拥有的,但我想 OP 想要返回一个列表。set(alice)
in list1
set
评论