2013-04-08 39 views
3

我想知道是否有任何其他方式循環和操作位於單獨數組中的數據。有沒有比使用循環更清潔的方式

import numpy as np 

a = np.arange(2) 
b = np.arange(5) 
c = np.arange(5) 

l1 = [] 
for x in a: 
    l2 = [] 
    for y in b: 
     l3 = [] 
     y = x + 1 
     for z in c: 
      z = x + y 
      t = (x,y,z) 
      l3.append(t) 
     l2.append(l3) 
    l1.append(l2) 
print l1 
+6

究竟是代碼試圖做什麼? – NPE 2013-04-08 07:17:54

+1

請更具體一點,你想做什麼? – vivek 2013-04-08 07:28:09

+0

Im建立基於不同參數的數據然後繪製它們。數組就是那些參數。 – Wallace 2013-04-08 07:31:02

回答

7

此代碼完全符合您的操作。如果你喜歡

def gen_method(lst, r1, r2): 
    return ([[(i, i+1, 1+(i*2))]*r2]*r1 for i in lst) 

測試它自己:

def method(lst, range1, range2): 
    for i in lst: 
     yield [[(i, i+1, 1+(i*2))]*range2]*range1 

甚至可以變成一臺發電機的表達。


我的測試:

a = range(2) 
b = range(5) 
c = range(5) 

def your_method(a, b, c): 
    l1 = [] 
    for x in a: 
     l2 = [] 
     for y in b: 
      l3 = [] 
      y = x + 1 
      for z in c: 
       z = x + y 
       t = (x,y,z) 
       l3.append(t) 
      l2.append(l3) 
     l1.append(l2) 
    return l1 

def my_method(lst, range1, range2): 
    for i in lst: 
     yield [[(i, i+1, 1+(i*2))]*range2]*range1 

yours = your_method(a, b, c) 
mine = list(my_method(a, len(b), len(c))) 

print yours 
print '===' 
print mine 
print '===' 
print yours == mine 

>>> 
[[[(0, 1, 1), (0, 1, 1), (0, 1, 1), (0, 1, 1), (0, 1, 1)], [(0, 1, 1), (0, 1, 1), (0, 1, 1), (0, 1, 1), (0, 1, 1)], [(0, 1, 1), (0, 1, 1), (0, 1, 1), (0, 1, 1), (0, 1, 1)], [(0, 1, 1), (0, 1, 1), (0, 1, 1), (0, 1, 1), (0, 1, 1)], [(0, 1, 1), (0, 1, 1), (0, 1, 1), (0, 1, 1), (0, 1, 1)]], [[(1, 2, 3), (1, 2, 3), (1, 2, 3), (1, 2, 3), (1, 2, 3)], [(1, 2, 3), (1, 2, 3), (1, 2, 3), (1, 2, 3), (1, 2, 3)], [(1, 2, 3), (1, 2, 3), (1, 2, 3), (1, 2, 3), (1, 2, 3)], [(1, 2, 3), (1, 2, 3), (1, 2, 3), (1, 2, 3), (1, 2, 3)], [(1, 2, 3), (1, 2, 3), (1, 2, 3), (1, 2, 3), (1, 2, 3)]]] 
=== 
[[[(0, 1, 1), (0, 1, 1), (0, 1, 1), (0, 1, 1), (0, 1, 1)], [(0, 1, 1), (0, 1, 1), (0, 1, 1), (0, 1, 1), (0, 1, 1)], [(0, 1, 1), (0, 1, 1), (0, 1, 1), (0, 1, 1), (0, 1, 1)], [(0, 1, 1), (0, 1, 1), (0, 1, 1), (0, 1, 1), (0, 1, 1)], [(0, 1, 1), (0, 1, 1), (0, 1, 1), (0, 1, 1), (0, 1, 1)]], [[(1, 2, 3), (1, 2, 3), (1, 2, 3), (1, 2, 3), (1, 2, 3)], [(1, 2, 3), (1, 2, 3), (1, 2, 3), (1, 2, 3), (1, 2, 3)], [(1, 2, 3), (1, 2, 3), (1, 2, 3), (1, 2, 3), (1, 2, 3)], [(1, 2, 3), (1, 2, 3), (1, 2, 3), (1, 2, 3), (1, 2, 3)], [(1, 2, 3), (1, 2, 3), (1, 2, 3), (1, 2, 3), (1, 2, 3)]]] 
=== 
True 
1

那麼,你可以使用列表解析壓縮代碼:

[[[(x,x+1,x*2 +1)]*len(c)]*len(b) for x in a] 

這樣做是什麼在所有的x環路,並創建一個列表元素,其中每個元素是爲b中所有y生成的列表,其中的每個元素列表爲(x,x+1,2*x+1),對於c中的所有z。

+0

這會比我的例子花費很多時間,循環遍歷'c'和'b'中的項目是浪費時間,你只需要它們的長度。您可以使用timeit模塊進行檢查。 – 2013-04-08 07:48:27

+0

@InbarRose:現在呢? – Manishearth 2013-04-08 07:54:40

+0

是的,現在它幾乎和我的一樣,但由於它不是一個生成器表達式,它會佔用更多的內存。這一切都取決於偏好,我更喜歡生成器,有些更喜歡簡單的列表。另外 - 你做'x + x + 1',我做'1+(x * 2)',這個更快。 – 2013-04-08 07:56:09

0

的另一種方法是使用itertools,結果列表轉換爲numpy array並重塑其

import numpy as np 
import itertools as it 

a = np.arange(2) 
b = np.arange(5) 
c = np.arange(5) 

l1 = np.array([(i, i+1, i*2+1) for i, rb, rb in it.product(a, b, c)]) 
l1 = l1.reshape(len(a), len(b), len(c), len(d[0])) 

這可能是該得到更多的內存消耗比所有其他的方法大小的增加,但它 只有兩行和 爲每個三元組創建獨特元素,而不是僅創建指向同一對象的多個指針。

編輯

的其他方式,也允許保持三聯(I,I + 1,我* 1 + 1)的列表是:

l1 = np.empty([len(a), len(b), len(c)], dtype=object) 
for i, rb, rb in it.product(a, b, c): 
    l1[i,ra, rb] = (i, i+1, i*2+1) 
+0

「只有兩個行「的代碼長度與效率無關,實際上,python是關於可讀性的,無論如何,我的答案之一是*也是* 1的內存(在一個函數調用中 - 所以這也是2行)....這不是更快,也沒有更多的可讀性。 – 2013-04-08 15:33:23

+0

你是否因爲「只有兩條線」而低估了我?我知道短暫並不意味着更有效率,我也不是在儘量縮短比賽時間。我只想寫一個簡短的解決方案,沒有(我認爲)影響其他兩個答案的問題。 – 2013-04-08 16:13:53

相關問題