3

我想计算毕达哥拉斯三元组(下面的代码)并且我想无限地计算我如何在不使用三个 for 循环的情况下做到这一点?我可以以某种方式使用 for 循环吗?谢谢。

import math

def main():
    for x in range (10000, 1000):
        for y in range (10000, 1000):
            for z in range(10000, 1000):
                if x*x == y*y + z*z:
                    print y, z, x
                    print '-'*50

if __name__ == '__main__':
    main()  
4

12 回答 12

8

一般来说,你不能。三个变量,三个循环。

但这是一个特例,没有人指出。你可以用两个循环来解决这个问题。

此外,检查 y、z 和 z、y 也没有意义。

哦,还有range(10000, 1000) = []

import math

for x in range(1, 1000):
  for y in range(x, 1000):
      z = math.sqrt(x**2 + y**2)
      if int(z) == z:
        print x, y, int(z)
        print '-'*50
于 2009-02-25T21:52:06.447 回答
4

您只需要两个循环 - 只需检查是否math.sqrt(x*x+y*y)是整数。如果是,你已经发现了一个毕达哥拉斯三元组。

我是 Python 新手,所以我不知道range(10000, 1000)它在哪里开始和停止?我问是因为您可以通过设置ystart at范围x而不是修复它来将运行时间减半,因为加法是可交换的。

编辑: 这个答案是我得到的,如果我知道更多的 Python,我会写什么。

于 2009-02-25T21:55:26.967 回答
4

您可以将代码安排在一个主循环中,如下所示:

MIN = 10000
MAX = 10010
a = [MIN, MIN, MIN]
while True:
    print a
    for i in range(len(a)):
        a[i] = a[i] + 1
        if a[i] < MAX:
            break
        a[i] = MIN
        i += 1
    else:
        break

而不是print a,您可以在那里进行毕达哥拉斯三元组测试。这将适用于任意数量的维度。

如果您真的想无限地执行此操作,则必须使用不同的迭代技术,例如对角化

于 2009-02-25T21:58:16.790 回答
2

这是一个使用迭代器的高效版本,它按顺序生成所有这样的三元组。这里的技巧是遍历所有 N 的总和为 N 的 (x,y) 对的集合。

导入数学
导入迭代工具

def all_int_pairs():
    “生成所有正整数对”
    对于 itertools.count(1) 中的 n:
        对于 xrange(1,n/2+1) 中的 x:
            产量 x,nx

对于 all_int_pairs() 中的 x,y:
    z = math.sqrt(x**2 + y**2)
    如果 int(z) == z:
        打印 x, y, int(z)
        打印'-'*50
于 2009-02-26T01:04:36.060 回答
2

使用xrange而不是range应该使用更少的内存,特别是如果您想尝试大范围。

于 2009-02-25T22:39:31.387 回答
1

这与 Can Berk Guder 的答案相同,但作为生成器完成,只是为了好玩。它在这里的嵌套循环并不是真的有用,但它通常可以是一个更清洁的解决方案。你的函数产生结果;您稍后会担心要检索多少。

import math

def triplets(limit):
    for x in range(1, limit):
        for y in range(x, limit):
            z = math.sqrt(x**2 + y**2)
            if int(z) == z:
                yield x, y, int(z)

for x, y, z in triplets(10):
    print x, y, z
    print "-" * 50
于 2009-02-25T22:58:04.103 回答
1

不是最有效的(Python 将构建一个包含十亿个元组的数组),但这是一个循环:

for x, y, z in [(x, y, z) for x in range(10000, 11000) for y in range(10000, 11000) for z in range(10000, 11000)]:
    if x*x == y*y + z*z:
        print y, z, x
        print '-'*50

或者,正如Christian Witts所建议的,

for x, y, z in ((x, y, z) for x in xrange(10000, 11000) for y in xrange(10000, 11000) for z in xrange(10000, 11000)):
    if x*x == y*y + z*z:
        print y, z, x
        print '-'*50

(假设 Python >= 2.4)使用生成器而不是构建十亿元组数组。

无论哪种方式,您都不应该这样编写代码......您的嵌套循环的初始代码更清晰。

于 2009-02-25T22:13:33.600 回答
1

使用相同的算法(有关更好的方法,请参阅其他答案),您可以使用 itertools.count 来获得一个永远运行的循环。

import itertools

for x in itertools.count(1):
    for y in xrange(1, x):
         for z in xrange(1, y):
              if x*x == y*y + z*z:
                  print x, y, z
于 2009-02-25T23:13:41.040 回答
0

除了已经发布的内容外,人们还期望三个集合的三个循环。其他任何事情都可能会变得非常混乱,并且不会提供额外的好处。

于 2009-02-25T21:55:15.453 回答
0

无穷大至少需要三个循环。要使某些东西变得灵活,需要大量的循环。此示例是Project Euler 问题 9及更多问题的解决方案。

#!/usr/bin/env python

def fcount(start=1):
    n = float(start)
    while True:
        yield n
        n += 1

def find_triples():
    for c in fcount():
        for b in fcount():
            if b > c:
                break
            for a in fcount():
                if a > b:
                    break
                if a ** 2 + b ** 2 == c ** 2:
                    yield (a, b, c)

def triples_by_sum(targetsum):
    for a, b, c in find_triples():
        if a + b + c == targetsum:
            yield a, b, c
        if c > targetsum:
            break

if __name__ == '__main__':
    # Finds multiple triples
    for a, b, c in triples_by_sum(252):
        print a, b, c
    # Finds single triples
    a, b, c = triples_by_sum(1000).next()
    print a, b, c
    # Goes forever
    for a, b, c in find_triples():
        print a, b, c
于 2009-02-26T02:52:46.863 回答
0

如果你想数到无穷大..

创建一个从零开始计数且永不停止的生成器函数,并在其上使用 for 循环

def inf():
   i = 0
   while True:
     yield i
     i = i + 1

for i in inf():
    print i  # or do whatever you want!

不知道有没有这样的内置函数

于 2009-02-25T23:08:12.237 回答
0

改用 itertools.product 怎么样?

# range is [10000, 1000)
for x, y, z in itertools.product(range(10000, 1000, -1), repeat=3): 
    if x * x == y * y + z * z:
        print(y, z, x)

稍微优化一下:

for x, y, z in itertools.product(range(10000, 1000, -1), repeat=3):
    if y >= x or z >= x or x >= (y + z) or z < y:
        continue
    if x * x == y * y + z * z:
        print(y, z, x)

编辑:这里我只是给出一种使用方法,product而不是多个 for 循环。你可以在上面的帖子中找到更有效的方法。

于 2011-08-04T07:22:53.783 回答