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

1 つ目は非常に単純です。

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

2 番目はもっと複雑なものを必要としますが、基本的には同じです。

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

どちらもジェネレーター式を使用します。これは、追加のリスト作成を必要としないリスト内包表記に似ています。

于 2010-12-01T20:57:18.420 に答える
5

与えられたこれら2つの方法を確認するための速度比較を次に示します.

まず、100000 エントリのリストを作成します。つまらないし、弦が短いので本物のサンプルではないかもしれませんが、今は気にしていません。

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

まず、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)
... 

素敵でシンプル。次に、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

要約: リストを 2 回調べても心配はいりません。ジェネレータ内包表記と組み合わせると、list.append のオーバーヘッドよりもコストがかかりません。Michael のソリューションは、100000 エントリで約 15% 高速です。

'%(...)s' % dict()第二に、またはを使用する必要があるかどうかがあります'%s' % tuple()。マイケルの答えを2つのうちのより速くて簡単なものとして取り上げると、次のようになります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

の 2 倍以下のシェードmichael2


Python 2.6 で導入された「文字列フォーマットの未来」というベンチマークへの最後の追加str.formatです (理由はまだわかりませんが、私%の .

>>> 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

9.70 の代わりに 11.81、7.81 の代わりに 9.89 - 20 ~ 25% 遅くなります (それを使用する関数の 2 番目の式に過ぎないことも考慮してください。

于 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 に答える