如何从多个列表中创建字典?

时间:2013-04-22 20:49:01

标签: python list dictionary

我有许多相互对应的列表:

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中有效地做到这一点?

3 个答案:

答案 0 :(得分:4)

两次使用zip

>>> 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)}

与genexp的时序比较:

>>> 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并不会改变很多时间,但对于大数据集来说,内存效率会更高。

答案 1 :(得分: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)}

如果数据集非常大,您可以使用itertools.izip()来避免zip()创建整个数据集的全新副本。此函数将返回一个迭代器,它将在请求时提供每个压缩元素,而不是将整个新结构保存在内存中。 (结果将是相同的,但在较大的数据集上应该更快。)

>>> 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)}

答案 2 :(得分: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()

对于大型数据集可能会更快