2012-08-01 132 views
5

Python新手在這裏,運行2.7。函數迭代打印但不返回

我正在嘗試創建一個程序,該程序使用函數來生成文本,然後將函數生成的文本輸出到文件中。

如果只是打印在PowerShell中的功能(如下:http://codepad.org/KftHaO6x),進行迭代,因爲我希望它:

def writecode (q, a, b, c): 
    while b < q: 
     b = b + 1 
     print "v%d_%d_%d = pairwise (caps[%d],sals[%d],poss[%d],poss[%d],poss[%d],pos_range)" %(a,b,c,a,a,a,b,c) 
     print "votes%d_%d.append(v%d_%d_%d)" % (b,c,a,b,c,) 
     print "v%d_%d_%d = pairwise (caps[%d],sals[%d],poss[%d],poss[%d],poss[%d],pos_range)" %(a,c,b,a,a,a,c,b) 
     print "votes%d_%d.append(v%d_%d_%d)" % (c,b,a,c,b) 

writecode (5,1,0,4) 

當試圖輸出功能到一個文件中(這樣的:http://codepad.org/8GJpp9QY)它只提供了1個值,即不重複:

def writecode (q, a, b, c): 
    while b < q: 
     b = b + 1 
     data_to_write = "v%d_%d_%d = pairwise (caps[%d],sals[%d],poss[%d],poss[%d],poss[%d],pos_range)" %(a,b,c,a,a,a,b,c) 
     data_to_write_two = "votes%d_%d.append(v%d_%d_%d)" % (b,c,a,b,c,) 
     data_to_write_three = "v%d_%d_%d = pairwise (caps[%d],sals[%d],poss[%d],poss[%d],poss[%d],pos_range)" %(a,c,b,a,a,a,c,b) 
     data_to_write_four = "votes%d_%d.append(v%d_%d_%d)" % (c,b,a,c,b) 
     return data_to_write 
     return data_to_write_two 
     return data_to_write_three 
     return data_to_write_four 

x = writecode (5,1,0,4) 

out_file = open("code.txt", "a") 
out_file.write(x) 
out_file.close() 

這是爲什麼,我怎麼可以使輸出功能迭代(如將其與打印一樣)?

+5

的'return'聲明** **終止函數(如在大多數(全部)的語言嗎?):http://docs.python.org/reference/simple_stmts.html#the-return-statement – 2012-08-01 20:17:14

+3

感謝Hamish將實際的代碼放在這裏的問題中...... – 2012-08-01 20:18:34

+2

回過頭來,你似乎在使用代碼生成。你爲什麼不直接執行代碼?或者說一些關於你更大的任務? – 2012-08-01 20:23:27

回答

2

在您用來寫入文件的版本中,該函數在while循環的第一次迭代之後返回(通過第一個return語句)。根據你所擁有的,你可能想是這樣的:

def writecode (q, a, b, c): 
    results = [] 
    while b < q: 
     b = b + 1 
     results.append("v%d_%d_%d = pairwise (caps[%d],sals[%d],poss[%d],poss[%d],poss[%d],pos_range)" % (a,b,c,a,a,a,b,c)) 
     results.append("votes%d_%d.append(v%d_%d_%d)" % (b,c,a,b,c,)) 
     results.append("v%d_%d_%d = pairwise (caps[%d],sals[%d],poss[%d],poss[%d],poss[%d],pos_range)" % (a,c,b,a,a,a,c,b)) 
     results.append("votes%d_%d.append(v%d_%d_%d)" % (c,b,a,c,b)) 
     results.append("") 
    return "\n".join(results) 

x = writecode (5,1,0,4) 

out_file = open("code.txt", "a") 
out_file.write(x) 
out_file.close() 

其中通過累加輸出的每一行到一個列表中工作,然後返回一個字符串與所有的結果與新行和結尾的新行連接在一起。

+0

謝謝,您提供的代碼完全符合我需要的內容。非常感激! – user1569317 2012-08-01 20:47:07

+0

@ user1569317:不客氣。 FWIW可能有更簡單的方法來完成你正在做的事情,或者至少讓它更容易閱讀。我所做的只是向你展示一種相對簡單的方式來獲得你的工作。 – martineau 2012-08-02 02:03:07

1

return立即存在的功能:

return離開當前函數調用與表達式列表(或None)作爲返回值。

你需要爲你去(或者,更好的性能,創造價值的listjoin末)建立的字符串。

5

你的問題是,你只能一次從一個函數return

def test(): 
    return 1 
    return 2 

x = test() 
# x is now 1 

你會希望用yield或返回值的元組:

def this_will_work(): 
    yield 1 
    yield 2 

x = list(this_will_work()) # See below for why we are using list 
# x is now [1, 2] 

def so_will_this: 
    return 1, 2 

x = so_will_this() 
# x is now (1, 2) 

使用yield變成你函數轉換爲可以迭代的generator - 如果您只對所有最終值感興趣,則可以使用list將發生器轉換爲發電機產生的所有值的列表。或者,您可以使用for ... in對其進行循環。

0

略有變化;我已經使用帶有命名字段的新式字符串格式,這應該更易於閱讀。

請注意,您正在生成一些重複的塊(在輸出中b == c會出現兩次的每種情況)。

from textwrap import dedent 

codeblock = dedent("""\ 
    v{a}_{b}_{c} = pairwise (caps[{a}],sals[{a}],poss[{a}],poss[{b}],poss[{c}],pos_range) 
    votes{b}_{c}.append(v{a}_{b}_{c}) 
    v{a}_{c}_{b} = pairwise (caps[{a}],sals[{a}],poss[{a}],poss[{c}],poss[{b}],pos_range) 
    votes{c}_{b}.append(v{a}_{c}_{b}) 
""") 

def get_code (q, a, b, c): 
    return ''.join(codeblock.format(a=a, b=b, c=c) for b in xrange(b, q)) 

def main(): 
    with open('code.txt', 'a') as outf: 
     outf.write(get_code(5,1,0,4)) 

if __name__=="__main__": 
    main()