以下是一些速度比较,以检查您获得的这两种方法。
首先,我们创建 100000 个条目的列表;由于字符串较短,无聊而且可能不是真正的样本,但我现在并不担心。
>>> items = [{"title_url": "abc", "id": i, "title": "def"} for i in xrange(100000)]
首先,迈克尔·姆罗泽克的回答:
>>> def michael():
... ', '.join(item['title'] for item in items)
... ','.join('<a href="/u/%(title_url)s">%(title)s</a>' % item for item in items)
...
很好很简单。然后 systempuntoout 的回答(注意,在这个阶段我只是比较迭代性能,所以我已经将 %s 和元组格式切换为 %()s dict 格式;稍后我会计时另一种方法):
>>> def systempuntoout():
... titles = []
... urls = []
... for item in items:
... titles.append(item['title'])
... urls.append('<a href="/u/%(title_url)s">%(title)s</a>' % item)
... ', '.join(titles)
... ','.join(urls)
...
很好。现在给他们计时:
>>> import timeit
>>> timeit.timeit(michael, number=100)
9.6959049701690674
>>> timeit.timeit(systempuntoout, number=100)
11.306489944458008
总结:不用担心遍历列表两次,结合生成器理解它比 list.append 的开销更便宜;Michael 的解决方案在 100000 个条目上大约快 15%。
其次,你是否应该使用'%(...)s' % dict()
或'%s' % tuple()
。将迈克尔的答案视为两者中更快更简单的答案,这里是michael2
:
>>> def michael2():
... ', '.join(item['title'] for item in items)
... ','.join('<a href="/u/%s">%s</a>' % (item['title_url'], item['title']) for item in items)
...
>>> timeit.timeit(michael2, number=100)
7.8054699897766113
因此,我们在这里得出一个明确的结论,即使用元组进行字符串格式化比使用 dict 更快——快了近 25%。因此,如果性能是一个问题并且您正在处理大量数据,请使用此方法michael2
。
如果你想看到一些真正可怕的东西,请使用 systempuntoout 的原始答案,并保留完整的类:
>>> def systempuntoout0():
... class node():
... titles = []
... urls = []
... def add_name(self, a_title):
... self.titles.append(a_title)
... def add_link(self, a_title_url, a_title):
... self.urls.append('<a href="/u/%s">%s</a>' % (a_title_url, a_title))
... node = node()
... for entry in items:
... node.add_name(entry["title"])
... node.add_link(entry["title_url"], entry["title"])
... ', '.join(node.titles)
... ','.join(node.urls)
...
>>> timeit.timeit(systempuntoout0, number=100)
15.253098011016846
比 慢一倍的阴影michael2
。
最后一个补充,对str.format
Python 2.6 中引入的基准测试,“字符串格式化的未来”(尽管我仍然不明白为什么,我喜欢我的%
,非常感谢;尤其是因为它更快)。
>>> def michael_format():
... ', '.join(item['title'] for item in items)
... ','.join('<a href="/u/{title_url}">{title}</a>'.format(**item) for item in items)
...
>>> timeit.timeit(michael_format, number=100)
11.809207916259766
>>> def michael2_format():
... ', '.join(item['title'] for item in items)
... ','.join('<a href="/u/{0}">{1}</a>'.format(item['title_url'], item['title']) for item in items)
...
>>> timeit.timeit(michael2_format, number=100)
9.8876869678497314
11.81 而不是 9.70,9.89 而不是 7.81 - 它慢了 20-25%(还要考虑它只是函数中使用它的第二个表达式。