循环遍历列表并创建单个字符串的最快方法是什么?

ens*_*are 2 python nested-lists

例如:

list = [{"title_url": "joe_white", "id": 1, "title": "Joe White"},
        {"title_url": "peter_black", "id": 2, "title": "Peter Black"}]
Run Code Online (Sandbox Code Playgroud)

我怎样才能有效地循环创建:

Joe White, Peter Black
<a href="/u/joe_white">Joe White</a>,<a href="/u/peter_black">Peter Black</a>
Run Code Online (Sandbox Code Playgroud)

谢谢.

Mic*_*zek 8

第一个很简单:

', '.join(item['title'] for item in list)
Run Code Online (Sandbox Code Playgroud)

第二个需要更复杂的东西,但基本上是相同的:

','.join('<a href="/u/%(title_url)s">%(title)s</a>' % item for item in list)
Run Code Online (Sandbox Code Playgroud)

两者都使用生成器表达式,类似于列表推导而不需要额外的列表创建


Chr*_*gan 5

这里有一些速度比较来检查你给出的这两种方法.

首先,我们创建了100000个条目的列表; 因为弦乐较短而无聊而且可能不是真正的样本,但我现在并不担心.

>>> items = [{"title_url": "abc", "id": i, "title": "def"} for i in xrange(100000)]
Run Code Online (Sandbox Code Playgroud)

首先,Michael Mrozek的回答是:

>>> def michael():
...     ', '.join(item['title'] for item in items)
...     ','.join('<a href="/u/%(title_url)s">%(title)s</a>' % item for item in items)
... 
Run Code Online (Sandbox Code Playgroud)

很好,很简单.然后系统出来的答案(请注意,在这个阶段我只是比较迭代性能,所以我已经切换%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)
... 
Run Code Online (Sandbox Code Playgroud)

很好.现在给他们时间:

>>> import timeit
>>> timeit.timeit(michael, number=100)
9.6959049701690674
>>> timeit.timeit(systempuntoout, number=100)
11.306489944458008
Run Code Online (Sandbox Code Playgroud)

总结:不要担心重复列表两次,结合生成器理解它比list.append的开销便宜; 迈克尔的解决方案在100000个条目上的速度提高了大约15%.

其次,是否应该使用'%(...)s' % dict()'%s' % tuple().将Michael的答案视为两者中更快更简单的答案,这里是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
Run Code Online (Sandbox Code Playgroud)

所以我们在这里得出一个明确的结论,字符串格式化的元组比字典更快 - 几乎快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
Run Code Online (Sandbox Code Playgroud)

阴影低于两倍michael2.


最后一个补充,对于str.formatPython 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
Run Code Online (Sandbox Code Playgroud)

11.81而不是9.70而不是7.81 - 它慢了20-25%(同时考虑到它只是函数中使用它的第二个表达式).