给定一个整数列表,我想检查第二个列表并从第一个列表中删除只能从第二个列表中的两个数字之和不的那些列表。因此,鉴于a = [3,19,20]
和b = [1,2,17]
,我想要[3,19]
。
看起来像是一个带有两个嵌套循环的cinch - 除了我已经遇到break
和continue
命令。
以下是我所拥有的:
def myFunction(list_a, list_b):
for i in list_a:
for a in list_b:
for b in list_b:
if a + b == i:
break
else:
continue
break
else:
continue
list_a.remove(i)
return list_a
我知道我需要做什么,只是语法似乎不必要地混淆。有人能告诉我一个更简单的方法吗? TIA!
答案 0 :(得分:4)
你可以这样做,
In [13]: from itertools import combinations
In [15]: [item for item in a if item in [sum(i) for i in combinations(b,2)]]
Out[15]: [3, 19]
combinations
将在b
中提供所有可能的组合,并获取总和列表。只需检查a
修改强>
如果您不想使用itertools
为其编写功能。像这样,
def comb(s):
for i, v1 in enumerate(s):
for j in range(i+1, len(s)):
yield [v1, s[j]]
result = [item for item in a if item in [sum(i) for i in comb(b)]]
答案 1 :(得分:1)
对代码的评论:
O(nm^2)
,其中n
的大小为list_a
,m
的大小为list_b
。这是非常低效的,但是问题的良好开端。 continue
和break
语句,这些语句可能导致难以调试的复杂代码。 list_a
中list_b
对O(n)
的每个项目。这是一种将问题分解为较小问题并将其用于解决更大问题的方法。 总的来说,我认为你的功能做得太多了,通过分解问题可以将逻辑压缩成更简单的代码。
另一种方法:
由于我发现此任务很有趣,我决定自己尝试一下。我概述的方法如下所示。
1。您可以先使用散列检查列表是否在def check_pairs(lst, sums):
lookup = set()
for x in lst:
current = sums - x
if current in lookup:
return True
lookup.add(x)
return False
时间内有一对给定的金额:
list_b
2。然后您可以使用此功能检查list_a
中的任何对是否等于def remove_first_sum(list_a, list_b):
new_list_a = []
for x in list_a:
check = check_pairs(list_b, x)
if check:
new_list_a.append(x)
return new_list_a
中迭代的数字总和:
list_a
其中list_b
中的数字会导致def remove_first_sum(list_a, list_b):
return [x for x in list_a if check_pairs(list_b, x)]
中的两个数字之和。
3。以上也可以用列表理解来编写:
>>> remove_first_sum([3,19,20], [1,2,17])
[3, 19]
>>> remove_first_sum([3,19,20,18], [1,2,17])
[3, 19, 18]
>>> remove_first_sum([1,2,5,6],[2,3,4])
[5, 6]
两者的工作原理如下:
O(n)
注意:总体而言,上述算法的时间复杂度为O(n)
,并不需要太复杂的任何事情。但是,这也会导致./install --auto-dotfiles
额外的辅助空间,因为保留一组来记录已经看到的项目。
答案 2 :(得分:1)
您可以先创建所有可能的总和组合,然后过滤掉不属于该组合列表的元素
定义输入列表
>>> a = [3,19,20]
>>> b = [1,2,17]
接下来,我们将定义两个元素之和的所有可能组合
>>> y = [i+j for k,j in enumerate(b) for i in b[k+1:]]
接下来,我们将一个函数应用于列表a
的每个元素,并检查它是否存在于上面计算的列表中。 map
函数可以与if/else
子句一起使用。如果else子句成功,map
将产生None
。为了满足这一需求,我们可以过滤列表以删除None
值
>>> list(filter(None, map(lambda x: x if x in y else None,a)))
以上操作将输出:
>>> [3,19]
您也可以将所有这些行合并为一行来编写一行,但我不推荐这样做。
答案 3 :(得分:0)
你可以尝试这样的事情:
a = [3,19,20]
b= [1,2,17,5]
n_m_s=[]
data=[n_m_s.append(i+j) for i in b for j in b if i+j in a]
print(set(n_m_s))
print("after remove")
final_data=[]
for j,i in enumerate(a):
if i not in n_m_s:
final_data.append(i)
print(final_data)
输出:
{19, 3}
after remove
[20]