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

4

3 回答 3

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 倍。显然,结果取决于迭代的大小,但我对使用 double 的事实非常有信心zip,至少在 CPython 2 上总是比显式循环快。生成器异常或for循环需要解释器比单次调用更多的工作zip,这消除了迭代过程的一些开销。

使用itertools.izip而不是zip不会改变太多时间,但对于大数据集来说内存效率要高得多。

于 2013-04-22T20:55:10.313 回答
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)}
于 2013-04-22T20:51:52.067 回答
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()

于 2013-04-22T20:55:29.257 回答