将列表中的所有元素相乘(另一个列表索引超出范围问题)

9

我正在编写的程序中,需要将列表中的每个元素与其他所有元素相乘,就像这样:

List = [i1, i2, i3]

Result = [i1*i2, i1*i3, i2*i3]

我已经在循环方面折腾了一段时间,但似乎无法让它工作。这是我目前的代码(无法工作,我知道为什么无法工作,只是想寻求建议):

def function():
    for j in range(len(list)):
        n = j+1
        for i in range(len(list)):

            if n+i > len(list):
                n -= 1
            x = factor[j] * factor[j+i]

            result.append(x)
    return

2
看一下itertools.product。 - Jean-François Fabre
3
我认为 itertools.combinations 更适合他的示例。 - BrenBarn
4个回答

24
from itertools import combinations

xs = [1, 2, 3]
products = [x1 * x2 for x1, x2 in combinations(xs, 2)]

4
input_list = [1, 2, 3, 4]
result_list = []

for i in range(len(input_list)):
    for j in range(i + 1, len(input_list)):
        result_list.append(input_list[i] * input_list[j])

print(result_list)

结果:

[2, 3, 4, 6, 8, 12]

1
[v1 * list1[j] for i, v1 in enumerate(list1) for j in xrange(i)]

itertools shmitertools..

虽然这是第二快的答案,但比itertools方法稍微慢一些,而且风格上略显欠缺。

In [22]: list1 = range(1000)

In [23]: timeit [x1 * x2 for x1, x2 in combinations(list1, 2)]
10 loops, best of 3: 52.8 ms per loop

In [24]: timeit [v1 * list1[j] for i, v1 in enumerate(list1) for j in xrange(i)]
10 loops, best of 3: 55.7 ms per loop

In [25]: def slow_answer(input_list):
    result_list = []
    for i in range(len(input_list)):
        for j in range(i + 1, len(input_list)):
            result_list.append(input_list[i] * input_list[j])
    return result_list
   ....: 

In [26]: timeit slow_answer(list1)
10 loops, best of 3: 95 ms per loop

2
请不要这样做。Python令人难以置信的迭代工具是使其如此出色的原因之一。通过索引进行迭代是明显的倒退步骤。它会导致更多的混乱和可读性降低,而且几乎从来不是必要的。 - jpmc26
确认了轻微的风格更改,但第二个xrange更难删除。 - user3684792
尝试使用for i in list1 for j in list1 - jpmc26
双重计数 - user3684792
是的,这就是为什么“组合”绝对是最好的答案。;D - jpmc26

1
作为FMc所说,itertools是最简单的解决方案。但是,看看你提供的代码有什么问题可能会有所帮助,而不仅仅是编写全新的代码。有三个问题:
1. 你为列表使用了两个不同的名称(list和factor)。
2. 当i为0时,你包括了形式为factor[j] * factor[j]的乘积。
3. 当i+n超出范围时,你的处理方式不起作用--它仍然可能导致某些超出范围的情况。
对于第3个问题的一个可能解决方案是在此时简单地退出内部循环:如果超出范围,则不想为此i或具有相同j的较大i执行任何操作。因此,这将给出
for j in range(len(factor)):
    n = j+1
    for i in range(len(factor)):
        # we are now going to look up factor[n+i] so need >=
        if n+i >= len(factor): 
            break
        # to ensure the second factor is later, use [n+i]>=j+1
        x = factor[j] * factor[n+i]
        result.append(x)

然而,更好的循环列表的方法是使用enumerate:

for j,x in enumerate(factor):
    # x is a list element, j is its index
    for y in factor[j+1:]:
        # loop through remaining elements by slicing
        result.append(x*y)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接