2

例如:

list = [{"title_url": "joe_white", "id": 1, "title": "Joe White"},
        {"title_url": "peter_black", "id": 2, "title": "Peter Black"}]

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

Joe White, Peter Black
<a href="/u/joe_white">Joe White</a>,<a href="/u/peter_black">Peter Black</a>

谢谢你。

4

3 回答 3

8

第一个非常简单:

', '.join(item['title'] for item in list)

第二个需要一些更复杂的东西,但本质上是一样的:

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

两者都使用生成器表达式,这类似于列表推导式,无需额外创建列表。

于 2010-12-01T20:57:18.420 回答
5

以下是一些速度比较,以检查您获得的这两种方法。

首先,我们创建 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.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

11.81 而不是 9.70,9.89 而不是 7.81 - 它慢了 20-25%(还要考虑它只是函数中使用它的第二个表达式。

于 2010-12-01T22:17:26.633 回答
1
class node():
    titles = []
    urls = []
    def add_name(self, a_title):
        self.titles.append(a_title)
    def add_url(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 list:
    node.add_name(entry["title"])
    node.add_url(entry["title_url"],entry["title"])

print ','.join(node.titles)
print ','.join(node.urls)
于 2010-12-01T21:05:27.950 回答