1. ホーム
  2. python

[解決済み] Python : dictのリスト、存在すればdictの値をインクリメントし、存在しなければ新しいdictを追加する

2022-08-09 19:27:37

質問

こんなことがしたいのですが。

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 は渡された callable を受け取り、それを呼び出してデフォルト値を取得します。 この場合、クラス int を渡しましたが、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()]