如何简化这个 python 迭代?

Posted

技术标签:

【中文标题】如何简化这个 python 迭代?【英文标题】:How can I simplifiy this python iteration? 【发布时间】:2019-09-15 00:00:40 【问题描述】:

我想获得三个(或更多)数字的所有可能组合。数字本身需要在 +-1 的范围内。范围是找到“相似的数字”——例如数字 3 需要迭代为 2,3,4。 例如我有:


    num1 = 3 
    num2 = 4
    num3 = 1

所以在这个例子中,我想要这三个数字和每个数字 +-1 的所有组合。 (例如 341、241、441;351、331、...)。所以对于示例数字,我应该得到 27 个组合。

第一个想法是在 python 中使用 3 个 for 循环,如下所示:


    num1 = 3
    num2 = 4
    num3 = 1

    def getSimilar(num1,num2,num3):

        num1 = n1 - 2

        for i in range (3):
            num1 = num1 + 1
            num2 = n2 - 2

            for j in range(3):

                num2 = num2 + 1
                num3 = n3 - 2

                for k in range(3):
                    num3 = num3 + 1
                    print(num1,num2,num3)

我得到的输出:


    2 3 0
    2 3 1
    2 3 2
    2 4 0
    2 4 1
    2 4 2
    2 5 0
    2 5 1
    2 5 2
    3 3 0
    3 3 1
    3 3 2
    3 4 0
    3 4 1
    3 4 2
    3 5 0
    3 5 1
    3 5 2
    4 3 0
    4 3 1
    4 3 2
    4 4 0
    4 4 1
    4 4 2
    4 5 0
    4 5 1
    4 5 2

在 python 中是否有一种更智能、更快捷的方法来执行此操作,而不是使用 3 个 for 循环?输出的顺序无关紧要。 我还有一个小问题: 如果一个数字是 0,我需要它只迭代到 0 和 1,而不是 -1。 所以输出为0; 4; 1 应该是:


    0 4 1
    0 4 2
    0 4 0

    0 3 1
    0 3 2
    0 3 0

    0 5 1
    0 5 2
    0 5 0

    1 4 1
    1 4 2
    1 4 0

    1 3 1
    1 3 2
    1 3 0

    1 5 1
    1 5 2
    1 5 0

【问题讨论】:

那么 3,4 和 1 是您要创建的数字的数字吗? Get the cartesian product of a series of lists?的可能重复 我想告诉你的一件事是打印内容会减慢计算时间。 @Hilea 我知道,这只是为了在我的代码中进行调试。不过谢谢! 【参考方案1】:

首先通过列表理解创建有效数字列表,然后使用itertools.product 创建可能的组合

from itertools import product
digits = [3,4,0,-1]

#Generate all possible digits
all_digits = [ (k-1,k,k+1) for k in digits]

#Valid digits, ensuring not to consider negative digits
valid_digits = [digits for digits in all_digits if all(x >= 0 for x in digits)]

#Create the iterator of all possible numbers
nums = product(*valid_digits)

#Print the combinations
for num in nums:
    print(*num)

输出将如下所示。

2 3
2 4
2 5
3 3
3 4
3 5
4 3
4 4
4 5

【讨论】:

我知道他没有明确说过,但如果我在这个解决方案中使用负数怎么办? 更新了@Error-SyntacticalRemorse!如果它看起来不错,您可以检查并投票吗?【参考方案2】:

你可以这样做:

from itertools import product

def getSimilar(*nums):
    return product(*(range(max(n - 1, 0), n + 2) for n in nums))

num1 = 3
num2 = 4
num3 = 1
for comb in getSimilar(num1, num2, num3):
    print(comb)

# (2, 3, 0)
# (2, 3, 1)
# (2, 3, 2)
# (2, 4, 0)
# ...

【讨论】:

修正了关于不产生负数的问题(起初没有读到)。【参考方案3】:

这是处理您的边缘情况的解决方案:

from itertools import product

nums = [0, 4, 1]
options = [[x - 1, x, x + 1] for x in nums]
result = [similar for similar in product(*options) if all(x >= 0 for x in similar)]
for x in result:
    print(x)

输出:

(0, 3, 0)
(0, 3, 1)
(0, 3, 2)
(0, 4, 0)
(0, 4, 1)
(0, 4, 2)
(0, 5, 0)
(0, 5, 1)
(0, 5, 2)
(1, 3, 0)
(1, 3, 1)
(1, 3, 2)
(1, 4, 0)
(1, 4, 1)
(1, 4, 2)
(1, 5, 0)
(1, 5, 1)
(1, 5, 2)

【讨论】:

这对我来说太完美了!谢谢! 如果它回答了您的问题,请不要忘记将其标记为答案!

以上是关于如何简化这个 python 迭代?的主要内容,如果未能解决你的问题,请参考以下文章

Python 优化:如何简化此代码?

如何获得每次迭代的时间执行? Python [重复]

如何在 Python 指针中有效地迭代数组?

如何限制 Python 中循环的迭代?

如果 Python 中的列表,如何迭代列表?

如何在python中检查可迭代的isinstance? [复制]