Python 如何在列表中查找成对和?
我有一张单子Python 如何在列表中查找成对和?,python,sum,Python,Sum,我有一张单子 [1, 2, 3, 3, 5, 5, 6, 7, 8, 9, 9] 我想找到所有的对和等于10 它应该是不同的数字对: i、 e 以下是我的想法,但我对下面的嵌套循环不满意: def test(x, n): pair = set() for i in range(len(x)): for j in range(len(x)): if i !=j: pair.add((x[i],x[j]) 如果我们
[1, 2, 3, 3, 5, 5, 6, 7, 8, 9, 9]
我想找到所有的对和等于10
它应该是不同的数字对:
i、 e
以下是我的想法,但我对下面的嵌套循环不满意:
def test(x, n):
pair = set()
for i in range(len(x)):
for j in range(len(x)):
if i !=j:
pair.add((x[i],x[j])
如果我们知道我们想要的总数,我们可以回答这个问题——对于每个数字,(总数)在列表中吗 我们可以将列表转换为一个集合,以使用哈希查找:
x = [1, 2, 3, 3, 5, 5, 5, 6, 6, 7, 8, 9, 9]
out = []
total = 10
for i in set(x):
if (total - i) in set(x) and i < (total+1)/2:
out.append((i, 10-i))
out
[(1, 9), (2, 8), (3, 7), (5, 5)]
x=[1,2,3,3,5,5,6,6,7,8,9]
out=[]
总数=10
对于集合中的i(x):
如果集合(x)中的(总计-i)和i<(总计+1)/2:
out.追加((i,10-i))
出来
[(1, 9), (2, 8), (3, 7), (5, 5)]
O(n)中的解决方案,处理排序后的值列表:
values = [1, 2, 3, 3, 5, 5, 6, 7, 8, 9, 9]
target = 10
i = 0
j = len(values) - 1
solutions = set()
while j > i:
if values[i] + values[j] < target:
i += 1
elif values[i] + values[j] > target:
j -= 1
else:
solutions.add((values[i], values[j]))
i += 1
j -= 1
print(solutions)
# {(2, 8), (5, 5), (1, 9), (3, 7)}
value=[1,2,3,3,5,5,6,7,8,9]
目标=10
i=0
j=len(值)-1
解决方案=集合()
而j>i:
如果值[i]+值[j]<目标:
i+=1
elif值[i]+值[j]>目标:
j-=1
其他:
解决方案。添加((值[i],值[j]))
i+=1
j-=1
打印(解决方案)
# {(2, 8), (5, 5), (1, 9), (3, 7)}
@Thierrylahuille的解决方案假设列表是预先排序的。如果该假设为假,则对列表进行排序将花费O(n logn)。相反,您可以使用collections.Counter
来实现O(n)时间复杂度,同时考虑列表中每个值的可用项数:
from collections import Counter
counts = Counter(x)
list({frozenset((10 - n, n)): (10 - n, n) for n in counts if counts[10 - n] > (n == 10 - n)}.values())
这将返回:
[(1, 9), (2, 8), (3, 7), (5, 5)]
像这样的怎么样
x=[1, 2, 3, 3, 5, 5, 6, 7, 8, 9, 9]
y=[]
for i in x[:5]:
q=10-i
w=(i,q)
if ((q in x) & (not(w in y))):
y.append(w)
这可能不是一个有效的代码来取代您的代码,我认为这段代码只是嵌套循环的一个替代方案您还可以使用一个集合来存储不同的值,从而得到一个O(n)解决方案。然而,你需要考虑偶数的目标。即使目标在列表中也需要其一半值的两个实例,但集合不会进行区分,并且当列表中实际上只有一个时,可以找到一对相等的值(例如,示例值中的target=12)
value=[1,2,3,3,5,5,6,7,8,9]
目标=10
valueSet=set(值)
halfValue=target//2
如果2*halfValue==目标和值。计数(halfValue)<2:halfValue-=1
如果v一条线性,则值集中的v的结果=[(v,target-v),不是最有效的:
导入itertools
res=set([itertools.组合(x,2)中的成对,如果总和(成对)==10])
# {(2, 8), (5, 5), (9, 1), (3, 7)}
在这里生成额外的组合,以及集合
构造函数的开销(不确定能否绕过后者)列表理解在这里很有效。尝试以下方法:
from itertools import permutations
x = [1, 2, 3, 3, 5, 5, 5, 6, 6, 7, 8, 9, 9]
target_number = 10
solutions = [pair for pair in permutations(x, 2) if sum(pair) == 10]
print('Solutions:', solutions)
输出:
解决方案:[(1,9)、(1,9)、(2,8)、(3,7)、(3,7)、(5,5)、(5,5)、(5,5)、(5,5)、(5,5)、(7,3)、(7,3)、(8,2)、(9,1)、(9,1)]
基本上,这个列表理解关注所有排列(x,2)的对
返回,但只保留总数等于10的问题。检查这一个,它使用的是itertools
。这个网站不是真正用于代码审查的。我重新打开了这个问题,因为它是重复的,因为那里的答案不正确且效率低下。也被称为两个和问题,检查一下,如果列表中没有足够的数字组成一对。例如,使用x=[5]
它应该返回[]
,但是这个答案将返回[(5,5)]
。对For
循环中的列表使用in
操作符实际上是一个嵌套循环。
values = [1, 2, 3, 3, 5, 5, 6, 7, 8, 9, 9]
target = 10
valueSet = set(values)
halfValue = target//2
if 2*halfValue == target and values.count(halfValue) < 2: halfValue -= 1
result = [ (v,target-v) for v in valueSet if v <= halfValue and target-v in valueSet ]
from itertools import permutations
x = [1, 2, 3, 3, 5, 5, 5, 6, 6, 7, 8, 9, 9]
target_number = 10
solutions = [pair for pair in permutations(x, 2) if sum(pair) == 10]
print('Solutions:', solutions)