簡體   English   中英

關於 python 中 for 循環的問題

[英]a question on for loops in python

我想計算畢達哥拉斯三元組(下面的代碼)並且我想無限地計算我如何在不使用三個 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()  

一般來說,你不能。 三個變量,三個循環。

但這是一個特例, 沒有人指出。 你可以用兩個循環來解決這個問題。

此外,檢查 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

您只需要兩個循環 - 只需檢查math.sqrt(x*x+y*y)是否為 integer。 如果是,你已經發現了一個畢達哥拉斯三元組。

我是 Python 的新手,所以我不知道range(10000, 1000)的作用 - 它在哪里開始和停止? 我問是因為你可以通過讓y的范圍從x開始而不是修復它來減半你的運行時間,因為加法是可交換的。

編輯: 這個答案是我得到的,如果我知道更多 Python,我會寫什么。

您可以將代碼安排在一個主循環中,如下所示:

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 這將適用於任意數量的維度。

如果您真的想無限地執行此操作,則必須使用不同的迭代技術,例如對角化

使用xrange代替range應該使用更少的 memory,特別是如果您想嘗試大范圍。

這是一個使用迭代器的高效版本,它按順序生成所有這樣的三元組。 這里的技巧是遍歷所有 N 的總和為 N 的 (x,y) 對的集合。

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

不是最有效的(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)使用生成器而不是構建十億元組數組。

無論哪種方式,您都不應該這樣編寫代碼......您的嵌套循環的初始代碼更清晰。

這與 Can Berk Guder 的答案相同,但作為生成器完成,只是為了好玩。 它在這里的嵌套循環並不是真的有用,但它通常可以是一個更清潔的解決方案。 您的 function 產生結果; 您稍后會擔心要檢索多少。

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

使用相同的算法(有關更好的方法,請參閱其他答案),您可以使用 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

除了已經發布的內容外,人們預計三個 collections 的三個循環。 其他任何事情都可能會變得非常混亂,並且不會提供額外的好處。

如果你想數到無窮大..

創建一個從零開始計數且永不停止的生成器 function,並在其上使用 for 循環

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

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

不知道有沒有這樣的內置 function

無窮大至少需要三個循環。 要使某些東西變得靈活,需要大量的循環。 此示例是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

改用 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 循環的方法。 你可以在上面的帖子中找到更有效的方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM