Python:列表字典,如果存在则递增值,否则添加新字典
我想做类似这样的事情。
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()]