2016-01-13 31 views
2

我有一個包含約500個元素的列表。爲了說明我有:Python基於列表中的信息連接數組

list3 = [ 'a', 'b', 'c', 'a' ] 

其中「A」,「B」,「C」是數組作爲名稱:

a = np.random.normal(0, 1, (500, 20)) 
b = np.random.normal(0, 1, (500, 30)) 
c = np.random.normal(0, 1, (500, 30)) 

我想連接列表中的數組中的順序出現在列表中。

所以,我的例子我想獲得:

C = np.concatenate((a, b, c, a), 1) 

我沒有一個想法如何處理這個以外的陣列存儲在一個字典,然後做一個字符串搜索和連接在一個for循環。有沒有一個優雅的方式來做到這一點?

回答

1

可以使用locals()字典的名字

d = locals() 
np.concatenate([d[x] for x in list3], 1) 
+0

這確實解決了OP所述的問題,但應該指出,如果包含在函數調用中,這將不起作用。例如'def concatenate(listx):#返回基於listx的連接列表,因爲locals不會在這個點包含全局對象。如果要連接的變量在相同的作用域中創建,則這將起作用。如果要在本地範圍內創建要連接的變量,我的解決方案會遇到類似的問題。 – Matthew

+0

@Mthethew True,只有當數組被定義爲全局變量時,它纔會在函數內部工作。 –

1

如果你想成爲緊湊:

np.concatenate([dict(a=a, b=b, c=c)[x] for x in list3], 1) 

或避免冗餘字典制作:

by_label = dict(a=a, b=b, c=c) 
np.concatenate([by_label[x] for x in list3], 1) 
0

你爲什麼不直接存儲,而不是他們的名字的變量? 像:

list3 = [a, b, c, a] 
C = np.concatenate(list3, axis=1) 

或者你可以使用eval()(不似乎建議報告的大部分時間):

list3 = ['a', 'b', 'c','a'] 
CC = np.concatenate([eval(i) for i in list3], axis=1) 
+0

好確定爲downvote :)使用'locals()'看起來比'eval()'更整潔! – mgc

+0

爲什麼不推薦使用eval? – Zanam

+0

我想是因爲評估「任何」表達式(例如,如果評估的表達式來自用戶輸入例如)可能是有風險的。有關更多詳細信息,請參閱http://stackoverflow.com/questions/1832940/is-using-eval-in-python-a-bad-practice(例如,可能經常有一種方法可以避免像'例如globals()'或'locals()')。 – mgc

1

您可以使用全局變量基於對象的名稱獲取數組。

globals()["a"] # array a 

所以可以做

np.concatenate(tuple(globals()[x] for x in list3),1) 
+0

只要在全局(或模塊級)範圍內創建要並置的數組,就可以工作。如果它們是在本地範圍內創建的(例如在函數調用中),那麼Brendan Abel的解決方案將是首選。 – Matthew

1

訪問變量可以很容易地得到所有局部變量的這樣一本詞典調用locals()函數。例如,要查找一個名爲變量a:

var = 'a' 
locals()[var] 

由於np.concatenate似乎採取一個元組,你可以使用:

lc = locals() 
C = np.concatenate(tuple(lc[var] for var in list3), 1)