127

私はそのようなことをしたいと思います。

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

どのようにできるのか ?タプルを取得して編集する必要があるのか​​ 、それともタプルのインデックスを把握する必要があるのか​​ わかりません。

助けはありますか?

4

6 に答える 6

238

それは物事を整理するための非常に奇妙な方法です。辞書に保存した場合、これは簡単です。

# 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、渡された callable を受け取り、それを呼び出してデフォルト値を取得します。この場合、クラスに渡しましたint。Python が呼び出すint()と、ゼロ値が返されます。そのため、初めて URL を参照すると、そのカウントは 0 に初期化され、カウントに 1 が追加されます。

しかし、カウントでいっぱいの辞書も一般的なパターンであるため、Python はすぐに使用できるクラスを提供します。クラスを呼び出してインスタンスをcontainers.Counter 作成しCounter、イテラブルを渡すだけです。キーが iterable からの値であり、値がキーが iterable に出現した回数のカウントであるディクショナリを構築します。上記の例は次のようになります。

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()]
于 2009-11-07T08:28:18.530 に答える
207

デフォルトを使用しても機能しますが、次の場合も同様です。

urls[url] = urls.get(url, 0) + 1

を使用.getすると、デフォルトの戻り値が存在しない場合に取得できます。デフォルトでは None ですが、私が送った場合は 0 です。

于 2009-11-07T08:31:00.540 に答える
29

defaultdictを使用します。

from collections import defaultdict

urls = defaultdict(int)

for url in list_of_urls:
    urls[url] += 1
于 2009-11-07T08:28:28.973 に答える
19

これは私にとって常にうまくいきます:

for url in list_of_urls:
    urls.setdefault(url, 0)
    urls[url] += 1
于 2010-11-04T12:14:30.853 に答える
4

まさにあなたのやり方でそれを行うには?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 を LIST として保存する必要がありますか? たとえば、URL文字列でインデックス付けされたdictとしてソートすると、よりクリーンになります。

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 番目の例で注意すべき点がいくつかあります。

  • dict for を使用すると、urls単一urlsurl. このアプローチはより高速になります。
  • 中括弧の代わりに使用dict( )すると、コードが短くなります
  • を変数名として使用list_of_urlsするurlsurl、コードの解析が非常に難しくなります。、 、など、より明確なものを見つけたほうがよいでしょurls_to_visitう。私は知っています、それはより長いです。しかし、それはより明確です。urls_already_visitedcurrent_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
于 2009-11-07T08:26:21.757 に答える
4

最初の場合を除いて、単語が表示されるたびに 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

于 2016-06-27T23:42:35.577 に答える