2013-04-22 26 views
2

我公司擁有一批名單是相互對應的是這樣的:如何從多個列表製作詞典?

ID_number = [1, 2, 3, 4, 5, 6, ...] 
x_pos = [43.2, 53.21, 34.2, ...] 
y_pos = [32.1, 42.1, 8.2, ...] 
z_pos = [1.3, 67.1, 24.3, ...] 

我希望能夠進行排序,拉,以及基於該ID_NUMBER的數據進行操作,所以我想打一個字典從這些名單就是這樣,

dictionary = {'id1':[x_pos1, y_pos1, z_pos1], 'id2':[x_pos2, y_pos2, z_pos2], ...} 

其中關鍵的是ID號和值是包含該ID號對應的數據列表。我將如何去有效地在Python中做這件事?

回答

2

zip()對此很有用。例如:

>>> ID_number = [1,2,3] 
>>> x_pos = [43.2, 53.21, 34.2] 
>>> y_pos = [32.1, 42.1, 8.2] 
>>> z_pos = [1.3, 67.1, 24.3] 
>>> dict((x[0], x[1:]) for x in zip(ID_number, x_pos, y_pos, z_pos)) 
{1: (43.200000000000003, 32.100000000000001, 1.3), 2: (53.210000000000001, 42.100000000000001, 67.099999999999994), 3: (34.200000000000003, 8.1999999999999993, 24.300000000000001)} 

如果數據集是相當大的,你能避免zip()的整個數據通過使用itertools.izip(),而不是設置的一個全新的副本的創建。該函數將返回一個迭代器,該請求將在請求時提供每個壓縮元素,而不是將整個新結構保存在內存中。 (結果將是相同的,但它應該是在較大的數據集更快。)

>>> import itertools 
>>> dict((x[0], x[1:]) for x in itertools.izip(ID_number, x_pos, y_pos, z_pos)) 
{1: (43.200000000000003, 32.100000000000001, 1.3), 2: (53.210000000000001, 42.100000000000001, 67.099999999999994), 3: (34.200000000000003, 8.1999999999999993, 24.300000000000001)} 
4

使用zip兩次:

與genexp
>>> ids = [1,2,3,4] 
>>> x_pos = [1.32, 2.34, 5.56, 8.79] 
>>> y_pos = [1.2, 2.3, 3.4, 4.5] 
>>> z_pos = [3.33, 2.22, 10.98, 10.1] 
>>> dict(zip(ids, zip(x_pos, y_pos, z_pos))) 
{1: (1.32, 1.2, 3.33), 2: (2.34, 2.3, 2.22), 3: (5.56, 3.4, 10.98), 4: (8.79, 4.5, 10.1)} 

時序比較:

>>> import timeit 
>>> timeit.timeit('dict(zip(ids, zip(x_pos, y_pos, z_pos)))', 'from __main__ import ids, x_pos, y_pos, z_pos') 
1.6184730529785156 
>>> timeit.timeit('dict((x[0], x[1:]) for x in zip(ids, x_pos, y_pos, z_pos))', 'from __main__ import ids, x_pos, y_pos, z_pos') 
2.5186140537261963 

因此,使用zip兩次比使用生成器表達式快大約1.5倍。很明顯,結果取決於迭代的大小,但我對使用雙zip的事實相當有信心,至少在CPython 2上總是比顯式循環快。發生器異常或for循環比單個調用zip需要更多的解釋工作,從而消除了迭代過程中的一些開銷。

使用itertools.izip而不是zip不會改變太多的時間,但對於大數據集而言,其存儲效率更高。

0
dictionary = {'id' + str(i): [x, y, z] 
       for i, x, y, z in zip(ID_number, x_pos, y_pos, z_pos)} 

大型數據集可能更快與itertools'izip()