【问题标题】:Python for loop inside for loop/Python for 循环内 for 循环/
【发布时间】:2025-12-13 01:05:04
【问题描述】:

我试图在一个列表中找到两个可以被彼此整除的数字。我已经设法做到这一点,方法是放置两个循环遍历同一个列表来比较数字,直到找到一对。

我的问题:

是否可以使用条件语句轻松将此代码压缩为一两行?

def FindDivisible(j):
    for i in j:
        for m in j:
            if int(i) % int(m) == 0 and int(i) != int(m):
                return([int(i),int(m)])

我明白这根本不是很 Pythonic。但是,我确实想知道这是否可能以及解决此问题的好方法。

【问题讨论】:

  • 我想你想要列表理解。有了理解,你可以在一两行中做到这一点
  • 您的代码没有正确缩进。除此之外,您当前的解决方案仅返回找到的第一对数字。例如,如果输入是j = [2, 4, 5, 6, 7, 8],您的代码将返回[4, 2]。这是你想要的吗?其他对呢?
  • 列表理解不能解决这个问题... 对 OP:你为什么要把它压缩成“一两行”?更少的代码并不是更好的代码。可读的代码是更好的代码,除非变量名不好,这段代码是可读的。
  • 看来作业没有好好计划。再努力一点。
  • @andyhasit,我认为你低估了列表理解

标签: python python-3.x for-loop


【解决方案1】:

这一行将获得可迭代j中元素的所有可分割组合:

[([int(i),int(m)]) for m in j for i in j if int(i) % int(m) == 0 and int(i) != int(m)]

以上只是将您的代码翻译成列表理解。一个区别是这将找到所有组合,而您的原始循环代码将仅返回第一个成功的组合。如果你想在第一次组合后退出,那么显式循环是正确的选择。

例如:

>>> j=range(2,5)
>>> [([int(i),int(m)]) for m in j for i in j if int(i) % int(m) == 0 and int(i) != int(m)]
[[4, 2]]

【讨论】:

  • OP 指定直到找到一对,这将返回所有。当然,你可以把第一个切掉。仍然不确定为什么 OP 首先要求这个,因为列表理解使它变得混乱。
  • @andyhasit 我发现列表理解更清晰,但我明白,根据每个人的先前经验,其他人可能会有不同的看法。此外,您对列表理解方法找到所有对,而不仅仅是第一个是正确的。答案中已说明。
  • 这很酷!我非常喜欢这个,即使它返回每个组合。我可能会使用它,只是让其他功能只使用他们需要的信息!谢谢!
【解决方案2】:

您或许可以使用 itertools.product

http://docs.python.org/library/itertools.html#itertools.product

示例

for var1, var2 in itertools.product(xrange(min1, max1, step1), xrange(min2, max2, step2)):
    # stuff

【讨论】:

    【解决方案3】:

    让我们使用itertool combinaison 和过滤器

    两行:

    from itertools import combinations
    alist =[(x,y) if  (x%y==0 or y%x==0 and x!=y ) else None for x,y in combinations(l, 2)]
    L = list(filter(None, alist))
    

    【讨论】:

      【解决方案4】:

      使用itertools.product。请注意,将int 映射到原始输入列表一次更简单,而不是不断转换单个元素。

      from itertools import product
      def find_divisible(j):
          return [(i, m) for (i, m) in product(map(int, j), repeat=2) 
                   if i % m == 0 and i != m]
      

      【讨论】: