将列表转为字典的最佳方法,键为每个对象的值?
我正在尝试把一个对象列表转换成一个字典。字典的值就是列表中的每个对象,而字典的键则是每个对象中找到的一个值。
下面是我正在使用的代码:
class SomeClass(object):
def __init__(self, name):
self.name = name
object_list = [
SomeClass(name='a'),
SomeClass(name='b'),
SomeClass(name='c'),
SomeClass(name='d'),
SomeClass(name='e'),
]
object_dict = {}
for an_object in object_list:
object_dict[an_object.name] = an_object
这段代码可以运行,但看起来有点丑,而且速度也有点慢。有没有人能给我一个更快或者更好的例子呢?
编辑:好的,感谢大家的回复。我必须说,看到一些更符合Python风格的方法看起来比我手动写的方式还要慢,我感到很惊讶。
编辑2:好的,我更新了测试代码,让它看起来更易读,因为测试的数量太多了,哈哈。
这是我们目前的代码,我在代码中加了作者的名字,如果我搞错了请告诉我。
from itertools import izip
import timeit
class SomeClass(object):
def __init__(self, name):
self.name = name
object_list = []
for i in range(5):
object_list.append(SomeClass(name=i))
def example_1():
'Original Code'
object_dict = {}
for an_object in object_list:
object_dict[an_object.name] = an_object
def example_2():
'Provided by hyperboreean'
d = dict(zip([o.name for o in object_list], object_list))
def example_3():
'Provided by Jason Baker'
d = dict([(an_object.name, an_object) for an_object in object_list])
def example_4():
"Added izip to hyperboreean's code, suggested by Chris Cameron"
d = dict(izip([o.name for o in object_list], object_list))
def example_5():
'zip, improved by John Fouhy'
d = dict(zip((o.name for o in object_list), object_list))
def example_6():
'izip, improved by John Fouhy'
d = dict(izip((o.name for o in object_list), object_list))
def example_7():
'Provided by Jason Baker, removed brackets by John Fouhy'
d = dict((an_object.name, an_object) for an_object in object_list)
timeits = []
for example_index in range(1, 8):
timeits.append(
timeit.Timer(
'example_%s()' % example_index,
'from __main__ import example_%s' % example_index)
)
for i in range(7):
timeit_object = timeits[i]
print 'Example #%s Result: "%s"' % (i+1, timeit_object.repeat(2))
当列表中有5个对象时,我得到的结果是:
Example #1 Result: "[1.2428441047668457, 1.2431108951568604]"
Example #2 Result: "[3.3567759990692139, 3.3188660144805908]"
Example #3 Result: "[2.8346641063690186, 2.8344728946685791]"
Example #4 Result: "[3.0710639953613281, 3.0573830604553223]"
Example #5 Result: "[5.2079918384552002, 5.2170760631561279]"
Example #6 Result: "[3.240635871887207, 3.2402129173278809]"
Example #7 Result: "[3.0856869220733643, 3.0688989162445068]"
而当有50个对象时:
Example #1 Result: "[9.8108220100402832, 9.9066231250762939]"
Example #2 Result: "[16.365023136138916, 16.213981151580811]"
Example #3 Result: "[15.77024507522583, 15.771029949188232]"
Example #4 Result: "[14.598290920257568, 14.591825008392334]"
Example #5 Result: "[20.644147872924805, 20.64064884185791]"
Example #6 Result: "[15.210831165313721, 15.212569952011108]"
Example #7 Result: "[17.317100048065186, 17.359367847442627]"
最后,当有500个对象时:
Example #1 Result: "[96.682723999023438, 96.678673028945923]"
Example #2 Result: "[137.49416589736938, 137.48705387115479]"
Example #3 Result: "[136.58069896697998, 136.5823769569397]"
Example #4 Result: "[115.0344090461731, 115.1088011264801]"
Example #5 Result: "[165.08325910568237, 165.06769108772278]"
Example #6 Result: "[128.95187497138977, 128.96077489852905]"
Example #7 Result: "[155.70515990257263, 155.74126601219177]"
感谢所有回复的人!我对这个结果感到非常惊讶。如果还有其他更快的方法,我很想听听。谢谢大家!
3 个回答
如果你关心速度的话,我们可以稍微改进一下。你的“详细”解决方案(其实也没问题)没有创建任何中间数据结构。另一方面,hyperboreean的解决方案,
d = dict(zip([o.name for o in object_list], object_list))
创建了两个不必要的列表:[o.name for o in object_list]
生成了一个列表,而 zip(_, _)
又生成了另一个列表。这两个列表的作用只是为了在创建字典时各自被遍历一次。
我们可以通过用生成器表达式替代列表推导式,来避免创建其中一个列表:
d = dict(zip((o.name for o in object_list), object_list))
把 zip
替换成 itertools.izip
会返回一个迭代器,从而避免创建第二个列表:
import itertools
d = dict(itertools.izip((o.name for o in object_list), object_list))
我们也可以用同样的方法修改Jason Baker的解决方案,只需删除方括号就可以了:
d = dict((an_object.name, an_object) for an_object in object_list)
在编程中,有时候我们需要处理一些数据,这些数据可能是从用户那里输入的,或者是从其他地方获取的。为了让程序能够理解这些数据,我们通常需要对它们进行一些转换或处理。
比如说,如果我们从用户那里得到了一个数字的字符串形式(像“123”),但我们想要用这个数字进行计算,那么我们就需要把它转换成真正的数字类型。这个过程就叫做“类型转换”。
在不同的编程语言中,类型转换的方式可能会有所不同,但基本的思路都是一样的。我们需要告诉程序:“嘿,这个东西其实是个数字,不是字符串。”这样程序才能正确地处理它。
有时候,程序在处理数据时可能会遇到一些问题,比如数据格式不对,或者数据类型不匹配。这时候,我们就需要仔细检查我们的数据,确保它们是正确的格式,这样程序才能顺利运行。
总之,处理数据时要特别注意数据的类型和格式,确保它们能够被程序正确理解和使用。
d = dict(zip([o.name for o in object_list], object_list))
在Python 3.0中,你可以使用字典推导式来快速创建字典:
{an_object.name : an_object for an_object in object_list}
在Python 2中也可以做到这一点,不过看起来就没那么好看了:
dict([(an_object.name, an_object) for an_object in object_list])