Skip to main content
 首页 » 编程设计

python之找到总和为 N 的对的更好方法

2025年05月04日12虾米哥

有没有更快的方法来写这个,该函数采用一个列表和一个值来查找该列表中总和为 N 且没有重复的数字值对我试图通过使用集合而不是使用列表来使其更快本身(但是我使用了 count(),我知道它是线性时间)我知道的任何建议都可能是一种方法

def pairsum_n(list1, value): 
 
    set1 = set(list1) 
    solution = {(min(i, value - i) , max(i, value - i)) for i in set1 if value - i in set1} 
    solution.remove((value/2,value/2)) if list1.count(value/2) < 2 else None            
    return solution 
""" 
    Example: value = 10, list1 = [1,2,3,4,5,6,7,8,9] 
    pairsum_n = { (1,9), (2,8), (3,7), (4,6) } 
    Example: value = 10,  list2 = [5,6,7,5,7,5,3] 
    pairsum_n = { (5,5), (3,7) } 
""" 

请您参考如下方法:

您的方法非常好,只需要进行一些调整即可提高效率。 itertools 很方便,但它并不真正适合这个任务,因为它会产生太多不需要的对。输入列表小还好,输入列表大就太慢了。

我们可以通过按顺序遍历数字来避免产生重复,当 i >= value/2 时停止,在使用集合去除重复项之后。

def pairsum_n(list1, value):  
    set1 = set(list1) 
    list1 = sorted(set1) 
    solution = [] 
    maxi = value / 2 
    for i in list1: 
        if i >= maxi: 
            break 
        j = value - i 
        if j in set1: 
            solution.append((i, j)) 
    return solution 

请注意,原始的 list1 没有被修改。此函数中的赋值创建一个新的本地 list1。如果您确实想要在输出中使用 (value/2, value/2),只需更改 break 条件即可。


这是一个稍微更紧凑的版本。

def pairsum_n(list1, value):  
    set1 = set(list1) 
    solution = [] 
    for i in sorted(set1): 
        j = value - i 
        if i >= j: 
            break 
        if j in set1: 
            solution.append((i, j)) 
    return solution 

可以进一步压缩它,例如使用 itertools.takewhile,但是它会更难阅读并且不会有任何效率上的改进。