实施两次求和问题的IndexError

时间:2019-06-14 14:40:12

标签: python algorithm

我写了一种算法,将一个列表中的两个数字相加,使其等于15或13或7,然后从原始列表中删除这些数字,然后重复该过程。直到开始列表中没有更多或更少的数字。始终存在以下问题:IndexError:列表分配索引超出范围。

我尝试使用字典或寻找其他算法,因为我正在做的是蛮力的。但是徒劳。

number = [10,5,14,1,12,2,7,6,10,3,8]
case1=15
case2=13

lc1i = []
lc1j = []
lc2i = []
lc2j = []

def seperate(number,case1,case2):

    for i in number:
        for j in number:
            if i+j == case1:
                lc1i.append(i)
                del number[i]
                lc1j.append(j)
                del number[j]


            elif i+j == case2:
                lc2i.append(i)
                del number[i]
                lc2j.append(j)
                del number[j]
    print(number)

seperate(number,case1,case2)

我希望最后有两个不同的字典:第一个具有所有对,总共15个,另一个对所有,总共13个。 但我有此消息:IndexError:列表分配索引超出范围

3 个答案:

答案 0 :(得分:1)

评论中已经指出了很多好东西,只想添加几件事。如果您要坚持当前的操作,可以做的是维护一个list已处理索引,而不是直接从原始list删除项目,只需检查当前索引是否已被处理(通过执行item in list)。像这样:

number = [10,5,14,1,12,2,7,6,10,3,8]
case1=15
case2=13

lc1i = []
lc1j = []
lc2i = []
lc2j = []

# we will store processed indexes to make sure they are not processed again
already_processed_indexes = []

def seperate(number,case1,case2):

    for idx1, i in enumerate(number):
        for idx2, j in enumerate(number):

            # check if indexes are already processed
            if idx1 in already_processed_indexes or idx2 in already_processed_indexes:
              continue

            if i+j == case1:
                lc1i.append(i)
                already_processed_indexes.append(idx1)
                lc1j.append(j)
                already_processed_indexes.append(idx2)


            elif i+j == case2:
                lc2i.append(i)
                already_processed_indexes.append(idx1)
                lc2j.append(j)
                already_processed_indexes.append(idx2)
    print(number)

seperate(number,case1,case2)

答案 1 :(得分:1)

如果顺序不重要,请不要使用列表,而应使用集合!

number = [10,5,14,1,12,2,7,6,10,3,8]
case1=15
case2=13

result1 = {0}
result2 = {0}

def seperate(number,case1,case2):

    for i in number:
        for j in number:
            if i+j == case1:
                result1.add(i)
            elif i+j == case2:
                result2.add(i)
    print(result1)
    print(result2)


seperate(number,case1,case2)

答案 2 :(得分:0)

已经有一些答案(甚至是一个公认的答案),但似乎没有一个考虑到问题中提出的要求:

  

我希望最后有两个不同的字典:第一个具有所有对,总共15个,另外所有对,总共13个。

(注意:我想用“列表”代替“字典”,因为在这种情况下字典没有意义,示例代码也适用于列表。)

此外,我假设相同的数字不能使用两次。对于给定的示例情况,这无关紧要,因为15、13和7是奇数,并且向其自身添加整数不能产生奇数。但是,在一般情况下,这可能很重要。

下面是我的解决方法,

  • ...可以处理任意数量的案例,例如问题中指出的“ 15或13或7”。该函数接受一个案例列表,而不是两个案例。
  • ...为每种情况返回一个索引对列表(因此返回值是一个索引元组列表的列表,但听起来比现在还糟...)
  • ...已更新,以解决许多pylint警告并符合PEP8样式指南。它还打印结果以供演示。

免责声明:对于所有数字只能使用一次还是在所有情况下使用,我还是不太清楚。因此,如果10和5是一个总和为15的对,那么10和3也是一个有效的对,等于13,还是10个只能使用一次?如果我对这个问题有误解,请告诉我,以便我更新代码。

代码

NUMBERS = [10, 5, 14, 1, 12, 2, 7, 6, 10, 3, 8]
CASES = [15, 13, 7]


def separate(numbers, cases):
    results = []
    for case in cases:
        result = []
        remaining_indices = list(range(len(numbers)))
        while remaining_indices:
            i = remaining_indices.pop(0)
            for j in remaining_indices:
                if numbers[i] + numbers[j] == case:
                    result.append((i, j))
                    remaining_indices.remove(j)
                    break
        results.append(result)
    return results


def main():
    case_results = separate(NUMBERS, CASES)

    # PRINT THE RESULTS:
    for idx, case in enumerate(CASES):
        for i, j in case_results[idx]:
            print('%2d + %2d = %2d' % (NUMBERS[i], NUMBERS[j], case))
        print('')

if __name__ == '__main__':
    main()

输出

10 +  5 = 15
14 +  1 = 15
12 +  3 = 15
 7 +  8 = 15

10 +  3 = 13
 5 +  8 = 13
 1 + 12 = 13
 7 +  6 = 13

 5 +  2 =  7
 1 +  6 =  7
相关问题