2009-02-25 106 views
3

我想calaculate pythagorean三胞胎(代码如下),我想无限计算如何做,而不使用三个for循环?我能以某种方式使用for循环吗?谢谢。python中的循环问题

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() 
+0

while语句有什么问题?你能否提供额外的信息,说明你为什么认为这必须用for语句来完成? – 2009-02-25 21:54:30

+0

如果你是为了解决项目欧拉问题而做的,那么就有一个简单的铅笔和纸张数学解决方案。 – jfs 2009-02-25 22:24:44

回答

8

一般情况下,你不能。三个变量,三个循环。

但是这是一个特殊情况,正如nobody指出的那样。你可以用两个循环来解决这个问题。

另外,检查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 
+0

+1:必须使用某种可迭代;序列或发生器。 – 2009-02-25 21:53:49

+0

是的,这就是我所掌握的,以及如果我知道更多Python,我会写些什么。 – 2009-02-26 00:02:15

0

除了已发布的内容之外,人们还会期待三个集合的三个循环。其他任何可能会变得非常混乱,并没有提供额外的好处。

4

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

我是新来的Python,所以我不知道range(10000, 1000)做什么 - 它在哪里开始和停止?我问,因为你可以将y的范围从x开始,而不是修复它,因为你可以减少运行时间,因为加法是可交换的。

编辑:This answer正是我所掌握的,以及如果我知道更多的Python会写些什么。

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的,你可以做你的勾股数的测试那里。这将适用于任意数量的维度。

如果你真的想无限地做到这一点,你将不得不使用不同的迭代技术,如diagonalization

+0

+1对角化---我想成为回答这个问题的人:( – zweiterlinde 2009-02-25 22:39:56

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)使用generators而不是构建一个亿元组数组。

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

+0

改变为“for x,y,z in((x,y,z)for x in xrange(10000,11000)for y in在xrange(10000,11000)中x的xrange(10000,11000)):“ 代替生成器表达式,并将范围更改为xrange,除非您已经使用Py3.0 – 2009-02-26 05:06:42

2

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

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 
0

如果你想计数到无穷..

创建一个从零计数和永不停止发电机功能,并使用for循环就可以了

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

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

我不知道是否已经有这样的内建函数

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 
2

下面是一个有效的版本,使用迭代器,生成为了所有这样的三元, 。这里的技巧是通过组(x,y)的双迭代向上 需要用于无穷总和为N,对于所有N.

 
import math 
import itertools 

def all_int_pairs(): 
    "generate all pairs of positive integers" 
    for n in itertools.count(1): 
     for x in xrange(1,n/2+1): 
      yield x,n-x 

for x,y in all_int_pairs(): 
    z = math.sqrt(x**2 + y**2) 
    if int(z) == z: 
     print x, y, int(z) 
     print '-'*50 
0

至少三个环。为了使灵活性需要大量的循环。此示例是Project Euler Problem 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 
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循环。你可以在上面的帖子中找到更有效的方法。