そのようなことをしたいです。
list_of_urls = ['http://www.google.fr/', 'http://www.google.fr/',
'http://www.google.cn/', 'http://www.google.com/',
'http://www.google.fr/', 'http://www.google.fr/',
'http://www.google.fr/', 'http://www.google.com/',
'http://www.google.fr/', 'http://www.google.com/',
'http://www.google.cn/']
urls = [{'url': 'http://www.google.fr/', 'nbr': 1}]
for url in list_of_urls:
if url in [f['url'] for f in urls]:
urls[??]['nbr'] += 1
else:
urls.append({'url': url, 'nbr': 1})
どのようにできるのか ?タプルを編集してタプルインデックスを計算する必要があるかどうかわかりませんか?
何か助け?
それは物事を整理する非常に奇妙な方法です。辞書に保存した場合、これは簡単です:
_# This example should work in any version of Python.
# urls_d will contain URL keys, with counts as values, like: {'http://www.google.fr/' : 1 }
urls_d = {}
for url in list_of_urls:
if not url in urls_d:
urls_d[url] = 1
else:
urls_d[url] += 1
_
カウントの辞書を更新するためのこのコードは、Pythonの一般的な「パターン」です。これは非常に一般的であるため、特別なデータ構造defaultdict
があり、これをさらに簡単にするために作成されています。
_from collections import defaultdict # available in Python 2.5 and newer
urls_d = defaultdict(int)
for url in list_of_urls:
urls_d[url] += 1
_
キーを使用してdefaultdict
にアクセスし、キーがdefaultdict
にまだない場合、キーはデフォルト値で自動的に追加されます。 defaultdict
は、渡された呼び出し可能オブジェクトを受け取り、それを呼び出してデフォルト値を取得します。この場合、クラスint
;を渡しました。 when Python呼び出しint()
はゼロの値を返します。したがって、URLを初めて参照するとき、そのカウントはゼロに初期化され、その後カウントに1を追加します。 。
しかし、カウントでいっぱいの辞書も一般的なパターンであるため、Pythonはすぐに使用できるクラスを提供します:_containers.Counter
_を呼び出すだけでCounter
インスタンスを作成します反復可能クラスを渡すクラス;キーが反復可能クラスの値であり、値が反復可能クラスにキーが出現した回数のカウントである辞書を作成します。
_from collections import Counter # available in Python 2.7 and newer
urls_d = Counter(list_of_urls)
_
本当にそれを示した方法で行う必要がある場合、最も簡単で最速の方法は、これら3つの例のいずれかを使用してから、必要なものをビルドすることです。
_from collections import defaultdict # available in Python 2.5 and newer
urls_d = defaultdict(int)
for url in list_of_urls:
urls_d[url] += 1
urls = [{"url": key, "nbr": value} for key, value in urls_d.items()]
_
Python 2.7以降を使用している場合は、ワンライナーで実行できます。
_from collections import Counter
urls = [{"url": key, "nbr": value} for key, value in Counter(list_of_urls).items()]
_
デフォルトを使用すると機能しますが、次のように機能します。
urls[url] = urls.get(url, 0) + 1
.get
を使用すると、デフォルトのリターンが存在しない場合に取得できます。デフォルトではNoneですが、送信した場合は0になります。
defaultdict を使用します。
from collections import defaultdict
urls = defaultdict(int)
for url in list_of_urls:
urls[url] += 1
これは私にとって常にうまくいきます:
for url in list_of_urls:
urls.setdefault(url, 0)
urls[url] += 1
まさにあなたの方法でそれを行うには? for ... else構造を使用できます
_for url in list_of_urls:
for url_dict in urls:
if url_dict['url'] == url:
url_dict['nbr'] += 1
break
else:
urls.append(dict(url=url, nbr=1))
_
しかし、それは非常に洗練されていません。訪問したURLをリストとして本当に保存する必要がありますか?たとえば、URL文字列でインデックス付けされた辞書としてソートすると、はるかにきれいになります:
_urls = {'http://www.google.fr/': dict(url='http://www.google.fr/', nbr=1)}
for url in list_of_urls:
if url in urls:
urls[url]['nbr'] += 1
else:
urls[url] = dict(url=url, nbr=1)
_
2番目の例で注意すべきいくつかの点:
urls
をテストするときに、urls
の辞書を使用してurl
リスト全体を調べる必要がないことを確認してください。このアプローチはより高速になります。dict( )
を使用すると、コードが短くなりますlist_of_urls
_、urls
、およびurl
を変数名として使用すると、コードの解析が非常に困難になります。 _urls_to_visit
_、_urls_already_visited
_、_current_url
_など、より明確なものを見つけることをお勧めします。私は知っている、それは長いです。しかし、それは明確です。そしてもちろん、dict(url='http://www.google.fr', nbr=1)
はあなた自身のデータ構造の単純化であると仮定しています。そうでなければ、urls
は単に
_urls = {'http://www.google.fr':1}
for url in list_of_urls:
if url in urls:
urls[url] += 1
else:
urls[url] = 1
_
defaultdict スタンスで非常にエレガントになります:
_urls = collections.defaultdict(int)
for url in list_of_urls:
urls[url] += 1
_
初めて例外を除き、Wordが表示されるたびにifステートメントのテストが失敗します。多数の単語をカウントしている場合、多くの単語がおそらく複数回出現します。値の初期化が1回だけ発生し、その値の増加が何度も発生する状況では、tryステートメントを使用する方が安価です。
urls_d = {}
for url in list_of_urls:
try:
urls_d[url] += 1
except KeyError:
urls_d[url] = 1
これについて詳しく読むことができます: https://wiki.python.org/moin/PythonSpeed/PerformanceTips