关于python:如何从返回字符数的字符串创建字典

How do I create a dictionary from a string returning the number of characters

本问题已经有最佳答案,请猛点这里访问。

我希望像'ddxxx'这样的字符串作为('d': 2, 'x': 3)返回。到目前为止,我已经尝试过

1
2
3
4
5
6
7
result = {}
for i in s:
    if i in s:
        result[i] += 1
    else:
        result[i] = 1
return result

其中s是字符串,但是我一直得到一个KeyError。例如,如果我将s设为'hello',返回的错误是:

1
2
result[i] += 1
KeyError: 'h'

使用collections.Counter可以很容易地解决这个问题。counter是用来计算事物的标准dict的子类型。它将自动确保在尝试增加字典中以前没有的内容时创建索引,因此您不需要自己检查它。

也可以将任何iterable传递给构造函数,使其自动计算该iterable中出现的项。由于字符串不能包含字符,您只需将字符串传递给它,即可计算所有字符:

1
2
3
4
5
6
7
8
9
>>> import collections
>>> s = 'ddxxx'
>>> result = collections.Counter(s)
>>> result
Counter({'x': 3, 'd': 2})
>>> result['x']
3
>>> result['d']
2

当然,手工操作也很好,而且您的代码几乎可以很好地实现这一点。因为您得到了一个KeyError,所以您试图访问字典中不存在的密钥。当你偶然遇到一个你以前没数过的新角色时,就会发生这种情况。你已经试着用你的if i in s检查来处理这个问题,但是你检查的是错误的控制。s是您的字符串,由于您正在迭代字符串的i字符,i in s将始终为真。相反,您要检查的是i是否已经作为密钥存在于字典result中。因为如果不添加它作为计数为1的新密钥:

1
2
3
4
if i in result:
    result[i] += 1
else:
    result[i] = 1

问题出在你的第二个条件上。if i in s正在检查字符串本身而不是字典中的字符。相反,它应该是if i in result.keys(),或者正如尼尔所说,它可以只是if i in result

例子:

1
2
3
4
5
6
7
8
9
10
def fun(s):
    result = {}
    for i in s:
        if i in result:
            result[i] += 1
        else:
            result[i] = 1
    return result  

print (fun('hello'))

这个会印出来的

1
{'h': 1, 'e': 1, 'l': 2, 'o': 1}


使用collections.Counter是明智的解决方案。但是,如果您想重新发明轮子,可以使用dict.get()方法,它允许您为丢失的键提供默认值:

1
2
3
4
5
6
7
s = 'hello'

result = {}
for c in s:
    result[c] = result.get(c, 0) + 1

print result

输出

1
{'h': 1, 'e': 1, 'l': 2, 'o': 1}

如果您不想使用collections模块,下面是一种简单的方法:

1
2
3
>>> st = 'ddxxx'
>>> {i:st.count(i) for i in set(st)}
{'x': 3, 'd': 2}