pythonic方式将列表元素与其索引相关联

时间:2010-05-14 03:28:03

标签: list dictionary python enumerate

我有一个值列表,我想将它们放在一个字典中,将每个值映射到它的索引。

我可以这样做:

>>> t = (5,6,7)
>>> d = dict(zip(t, range(len(t))))
>>> d
{5: 0, 6: 1, 7: 2}

这不错,但我正在寻找更优雅的东西。

我遇到过以下情况,但它与我需要的相反:

>>> d = dict(enumerate(t))
>>> d
{0: 5, 1: 6, 2: 7}

请分享您的解决方案,
谢谢

编辑:Python 2.6.4

对于包含1000个元素的列表,dict(zip)版本是最快的,生成器和列表推导版本几乎相同,它们慢约1.5倍,功能映射(反向)相当慢。

$ python -mtimeit -s“t = range(int(1e3))”“d = dict(zip(t,range(len(t))))”

1000循环,最佳3:277每循环usec

$ python -mtimeit -s“t = range(int(1e3))”“d = dict([(y,x)代表x,y代表枚举(t)])”
1000循环,最佳3:426每循环usec

$ python -mtimeit -s“t = range(int(1e3))”“d = dict(x,(y,x),枚举(t)中的y)”

1000循环,最好3:每循环使用437次

$ python -mtimeit -s“t = range(int(1e3))”“d = dict(map(reverse,enumerate(t)))”

100个循环,最佳3:3.66毫秒/循环

我尝试对较长的列表和较短的列表(1e2,1e4,1e5)运行相同的测试,每个循环的时间与列表的长度成线性比例。

有人可以计算py 2.7+版本吗?

6 个答案:

答案 0 :(得分:14)

您可以使用列表推导(或生成器,具体取决于您的python版本)为您的第二个示例执行简单的就地交换。


使用列表理解:

d = dict([(y,x) for x,y in enumerate(t)])

使用生成器表达式(Python 2.4及更高版本):

d = dict((y,x) for x,y in enumerate(t))

答案 1 :(得分:13)

在Python2.7 +中,您可以像这样编写

>>> t = (5,6,7)
>>> d = {x:i for i,x in enumerate(t)}
>>> print d
{5: 0, 6: 1, 7: 2}

答案 2 :(得分:4)

>>> dict((x,i) for i,x in enumerate(t))
{5: 0, 6: 1, 7: 2}
>>>

答案 3 :(得分:2)

您的所有元素都是唯一的(即您的列表永远不会是5,6,7,7)吗?只有当您的所有元素都是唯一的时,dict解决方案才会起作用。

通过存储索引,您实际上是复制信息,因为您可以简单地查询列表中项目的当前索引。复制信息通常不是最好的主意,因为它允许一组数据与另一组数据不同步。

如果正在修改列表,也没有什么可以防止您意外地将同一索引分配给多个项目。

当你只是从列表中获取索引时,为什么要尝试存储索引值?

答案 4 :(得分:2)

正如大家已经写过的那样,在Python 2.6中我会认为以下是最pythonic:

>>> dict((x, i) for i, x in enumerate(t))
{5: 0, 6: 1, 7: 2}

然而,在一个功能狂热的时刻,我会写:

>>> dict(map(reversed, enumerate(t)))
{5: 0, 6: 1, 7: 2}

答案 5 :(得分:0)

我最喜欢dict(zip(t,range(len(t)))。