将列表元素与其索引相关联的Pythonic方式
我有一个值列表,我想将它们放入一个字典中,该字典将每个值映射到它的索引。
我可以这样做:
>>> 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) for x,y in enumerate(t)]) ”
1000 个循环,最好是 3 个:每个循环 426 usec
$ python -mtimeit -s"t = range(int(1e3))" "d = dict((y,x) for x,y in enumerate(t))"< br> 1000 个循环,3 个循环中最好的:每个循环 437 usec
$ python -mtimeit -s"t = range(int(1e3))" "d = dict(map(reversed, enumerate(t)))"
100 个循环,最好的 3 个:每个循环 3.66 毫秒
我尝试对较长和较短的列表(1e2、1e4、1e5)运行相同的测试,并且每个循环的时间与列表的长度呈线性比例。
有人可以为 py 2.7+ 版本计时吗?
I have a list of values and I want to put them in a dictionary that would map each value to it's index.
I can do it this way:
>>> t = (5,6,7)
>>> d = dict(zip(t, range(len(t))))
>>> d
{5: 0, 6: 1, 7: 2}
this is not bad, but I'm looking for something more elegant.
I've come across the following, but it does the opposite of what I need:
>>> d = dict(enumerate(t))
>>> d
{0: 5, 1: 6, 2: 7}
Please share your solutions,
Thank you
EDIT: Python 2.6.4
For lists containing 1000 elements the dict(zip) version is the fastest, the generator and the list comprehension versions are virtually identical and they are ~1.5 times slower and the functional map(reversed) is considerably slower.
$ python -mtimeit -s"t = range(int(1e3))" "d = dict(zip(t, range(len(t))))"
1000 loops, best of 3: 277 usec per loop
$ python -mtimeit -s"t = range(int(1e3))" "d = dict([(y,x) for x,y in enumerate(t)])"
1000 loops, best of 3: 426 usec per loop
$ python -mtimeit -s"t = range(int(1e3))" "d = dict((y,x) for x,y in enumerate(t))"
1000 loops, best of 3: 437 usec per loop
$ python -mtimeit -s"t = range(int(1e3))" "d = dict(map(reversed, enumerate(t)))"
100 loops, best of 3: 3.66 msec per loop
I tried running the same tests for longer and for shorter lists (1e2, 1e4, 1e5) and the time per loop scales linearly with the length of the list.
Could somebody time py 2.7+ version?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
您可以使用列表理解(或生成器,具体取决于您的 python 版本)来为第二个示例执行简单的就地交换。
使用列表理解:
使用生成器表达式(Python 2.4 及更高版本):
You can use a list comprehension (or a generator, depending on your python version) to perform a simple in-place swap for your second example.
Using a list comprehension:
Using a generator expression (Python 2.4 and up):
在Python2.7+中可以这样写
In Python2.7+ you can write it like this
您的所有元素都是唯一的吗(即您的列表永远不会是 5、6、7、7)?仅当所有元素都是唯一的时,字典解决方案才有效。
通过存储索引,您实际上是在复制信息,因为您可以简单地查询列表中项目的当前索引。复制信息通常不是最好的主意,因为它可能导致一组数据与另一组数据不同步。
如果列表正在被修改,也没有什么可以阻止您意外地将相同的索引分配给多个项目。
当您可以简单地从列表中获取索引时,为什么要尝试存储索引值?
Are all your elements unique (i.e. your list would never be 5,6,7,7)? The dict solution will only work if all your elements are unique.
By storing the index, you're essentially duplicating information, since you could simply query the current index of the item in the list. Duplicating information is usually not the best idea, because it allows the possibility for one set of data to get out of sync with the other.
If the list is being modified, there's also nothing preventing you from accidentally assigning the same index to more than one item.
Why are you trying to store the index value, when you could simply get the index from the list?
正如每个人都已经写过的那样,在 Python 2.6 中,我认为以下内容是最 Pythonic 的:
尽管如此,在功能狂热的时刻我会写:
As everybody has already written, in Python 2.6 I would consider the following as the most pythonic:
Still, in a moment of functional frenzy I would write:
我最喜欢 dict(zip(t, range(len(t)))) 。
I like the dict(zip(t, range(len(t)))) best.