Python:列表字典,如果存在则递增值,否则添加新字典

145 投票
7 回答
210530 浏览
提问于 2025-04-15 15:45

我想做类似这样的事情。

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

我该怎么做呢?我不太确定是应该直接编辑这个元组,还是先弄清楚元组的索引?

有没有人能帮帮我?

7 个回答

30

使用 defaultdict

from collections import defaultdict

urls = defaultdict(int)

for url in list_of_urls:
    urls[url] += 1
239

使用默认的方式可以正常工作,但还有其他方法:

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

使用 .get 方法,如果你要查找的内容不存在,它可以给你一个默认的返回值。默认情况下,这个返回值是 None,但在我给你发的例子中,它会返回 0。

262

这是一种很奇怪的组织方式。如果你把数据存储在字典里,那就简单多了:

# 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类;当Python调用int()时,它会返回零。所以,当你第一次引用一个网址时,它的计数会被初始化为零,然后你再加一。

不过,字典里存满了计数也是一种常见的模式,所以Python提供了一个现成的类:containers.Counter。你只需要通过调用这个类并传入任何可迭代对象来创建一个Counter实例;它会构建一个字典,字典的键是来自可迭代对象的值,而值则是这个键在可迭代对象中出现的次数。上面的例子就变成了:

from collections import Counter  # available in Python 2.7 and newer

urls_d = Counter(list_of_urls)

如果你真的需要按照你展示的方式来做,最简单和最快的方法就是使用这三个例子中的任意一个,然后再构建你需要的那个。

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()]

撰写回答