使用字典理解(而不是计数器)查找 Python 中字符串中的字符数

问题描述 投票:0回答:5

我正在尝试创建一个单词及其在字符串中重复次数的字典。假设字符串如下所示

str1 = "aabbaba"

我想创建一本这样的字典

word_count = {'a':4,'b':3}

我正在尝试使用字典理解来做到这一点。 我做到了

dic = {x:dic[x]+1 if x in dic.keys() else x:1 for x in str}

这最终会给出一个错误:

  File "<stdin>", line 1
    dic = {x:dic[x]+1 if x in dic.keys() else x:1 for x in str}
                                               ^
SyntaxError: invalid syntax

有人能告诉我语法有什么问题吗?另外,如何使用字典理解创建这样的字典?

python string dictionary counter dictionary-comprehension
5个回答
16
投票

正如其他人所说,这最好用计数器来完成。

你还可以这样做:

>>> {e:str1.count(e) for e in set(str1)}
{'a': 4, 'b': 3}

但是对于每个唯一字符,它会遍历字符串 1+n 次(一次是为了创建集合,一次是为了每个唯一字母来计算它出现的次数。即,这具有二次运行时复杂性。)。如果长字符串中有很多唯一字符,结果会很糟糕...计数器仅遍历该字符串一次。

如果你不想要比使用

.count
更高效的导入版本,你可以使用
.setdefault
来制作计数器:

>>> count={}
>>> for c in str1:
...    count[c]=count.setdefault(c, 0)+1
... 
>>> count
{'a': 4, 'b': 3}

无论字符串有多长或有多少个唯一字符,都只遍历一次字符串。


如果您愿意,也可以使用

defaultdict

>>> from collections import defaultdict
>>> count=defaultdict(int)
>>> for c in str1:
...    count[c]+=1
... 
>>> count
defaultdict(<type 'int'>, {'a': 4, 'b': 3})
>>> dict(count)
{'a': 4, 'b': 3}

但是如果您要导入集合——请使用计数器!


9
投票

执行此操作的理想方法是使用

collections.Counter
:

>>> from collections import Counter
>>> str1 = "aabbaba"
>>> Counter(str1)
Counter({'a': 4, 'b': 3})

您无法通过简单的 dict 理解 表达式来实现此目的,因为您需要引用元素计数的先前值。正如 Dawg 的回答中提到的,作为解决方法,您可以使用

list.count(e)
来从
set
中的 dict 理解 表达式中的字符串中查找每个元素的计数。但时间复杂度将是
n*m
,因为它将遍历每个唯一元素的完整字符串(其中 m 是唯一元素),而对于计数器来说,它将是
n


4
投票

这是一个很好的案例

collections.Counter
:

>>> from collections import Counter
>>> Counter(str1)
Counter({'a': 4, 'b': 3})

它是 dict 子类,因此您可以像标准字典一样使用该对象:

>>> c = Counter(str1)
>>> c['a']
4

您也可以在不使用 Counter 类的情况下完成此操作。简单高效的 python 代码是:

>>> d = {}
>>> for x in str1:
...     d[x] = d.get(x, 0) + 1
... 
>>> d
{'a': 4, 'b': 3}

3
投票

请注意,这不是正确的方法,因为它不会多次计算重复字符(除了丢失原始字典中的其他字符之外),但这回答了 if-else 在理解中是否可能的原始问题并演示了如何做到这一点。

回答你的问题,是的,这是可能的,但方法是这样的:

dic = {x: (dic[x] + 1 if x in dic else 1) for x in str1}

条件仅应用于值,而不应用于键:值映射。

使用

dict.get
可以使上述内容更清楚:

dic = {x: dic.get(x, 0) + 1 for x in str1}
如果

x

 不在 
dic
 中,则返回 
0。

演示:

In [78]: s = "abcde"

In [79]: dic = {}

In [80]: dic = {x: (dic[x] + 1 if x in dic else 1) for x in s}

In [81]: dic 
Out[81]: {'a': 1, 'b': 1, 'c': 1, 'd': 1, 'e': 1}

In [82]: s = "abfg"

In [83]: dic = {x: dic.get(x, 0) + 1 for x in s}

In [84]: dic
Out[84]: {'a': 2, 'b': 2, 'f': 1, 'g': 1}

0
投票

请找到以下简单的解决方案。如果在字典中找不到键,这将创建当前值,否则将添加 1。

text = 'ABCDEEEEFED'

d = {}

for x in text:
    if x in d:
        d[x] = d[x] + 1
    else:
        d[x] = 1

© www.soinside.com 2019 - 2024. All rights reserved.