如何在不包含相同元素两次的情况下遍历列表?

Posted

技术标签:

【中文标题】如何在不包含相同元素两次的情况下遍历列表?【英文标题】:How to iterate through a list without including the same element twice? 【发布时间】:2021-03-10 21:48:27 【问题描述】:

我想知道如何在不包含两次相同数字的情况下遍历此列表。

import itertools

def sum_pairs(ints, s):
    indexes = []
    pair = []
    for numbers in itertools.combinations(ints,2):
        if sum(numbers) == s:
            pair.append(numbers)
            for n in numbers:
                indexes.append(ints.index(n))
    print(pair)
    print(indexes)

a = [10, 5, 2, 3, 7, 5]
target = 10

这是输出:

[(5, 5), (3, 7)]
[1, 1, 3, 4]

'pair' 正确输出 5 和 5 等于 10,但是当我使用变量 'indexes' 检查数字的来源时,我可以看到相同的 5 被使用了两次,而第二个 5 从未被考虑在内.我正在寻找的是如果它在同一个索引中,我如何修改它以不添加相同的数字两次。例如。索引的输出将是 [1, 5, 3, 4]。

非常感谢。

【问题讨论】:

【参考方案1】:

使用enumerate 将每个值的索引连同它一起走私:

import itertools

def sum_pairs(ints, s):
    indexes = []
    pair = []
    for (ix, x), (iy, y) in itertools.combinations(enumerate(ints),2):
        if x + y == s:
            pair.append((x, y))
            indexes += (ix, iy)
    print(pair)
    print(indexes)

a = [10, 5, 2, 3, 7, 5]
target = 10
sum_pairs(a, target)

哪个输出:

[(5, 5), (3, 7)]
[1, 5, 3, 4]

为了简化值的使用,我将 tuples 的 tuple 解包为名称(xy 是“真实”值,ixxiyy 的索引)。通过将索引附加到值,您始终准确地知道它来自哪里,而无需猜测它。

您对index 方法的使用不起作用,因为出于所有实际目的,您输入中的两个5 无法区分(在CPython 上,由于小的int 优化,它们实际上是同一个对象),而index 只返回它找到的第一个对象(并且每次都必须不必要地重新扫描它)。通过将索引与关联值保持一致,您根本不需要重新检查,您已经知道了。

【讨论】:

【参考方案2】:

改为在索引上运行组合。顺便说一句,您的索引的定义并不常见。如果您明白我的意思,请尝试使用下面的追加更改“扩展”

def sum_pairs(ints, s):
    indexes = []
    pair = []
    for numbers in itertools.combinations(range(len(ints)),2):
        if ints[numbers[0]]+ints[numbers[1]] == s:
            indexes.extend(numbers)
            pair.append((ints[numbers[0]],ints[numbers[1]]))
    print(pair)
    print(indexes)

【讨论】:

以上是关于如何在不包含相同元素两次的情况下遍历列表?的主要内容,如果未能解决你的问题,请参考以下文章

创建重复N次的单项列表

75. 颜色分类-两次遍历

如何在不实际使用枚举的情况下制作功能类似于枚举的代码?

带字符串的正则表达式:出现两次的字母对[关闭]

如何在不更改原始列表的情况下更改新列表?

如何在不跟踪索引的情况下将元素附加到列表?