2016-12-03 102 views
3

我正在尝试创建一个单词字典和它在字符串中重复的次数。如果字符串是像下面在Python中查找字符串中的字符数

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 

谁能告诉我什么是错的语法?另外,如何使用词典理解来创建这样一本词典?

+0

有你看了'Counter'? – dawg

+0

删除第二个x:第一个x:是两者的关键,if语句被解析为值的一部分 – Erotemic

+0

@dawg我知道计数器。我不想使用计数器。如果可能的话,我想用字典理解。 –

回答

5

正如其他人所说,这最好用一个Counter来完成。

你也可以这样做:

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

但是,如果你要导入的集合 - 使用计数器!

+0

为什么不在每次迭代时只count = collections.defaultdict(int)'而不是'setdefault' ? –

+1

@MichaelKohl避免进口?否则计数器是更好的选择 – Copperfield

6

理想的方式做,这是通过使用collections.Counter

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

无法通过简单的字典理解表达实现这一目标,你将需要参考以前的元素计数的值。正如在Dawg's answer中所提到的那样,作为一项工作,您可能会使用list.count(e)以查找来自set的字符串中的每个元素的计数。dict理解表达式。但时间复杂度将为n*m,因为它将遍历每个独特元素(其中m是唯一元素)的完整字符串,其中与计数器一样,它将为n

2

这是collections.Counter一个很好的案例:

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

它的字典子类,所以你可以与对象的工作方式类似于标准字典:

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

你可以做到这一点不使用反类以及。简单高效的Python代码为:

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

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

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

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

条件适用的价值不仅没有了密钥值映射。

以上可以使用dict.get更加清楚:如果x不在dic返回

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

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

问题是,你试过了吗? :) –

+0

@MoinuddinQuadri是的,它的工作原理:) – sirfz

+0

你的意思只是'dic = {x:dic.get(x,1)for x in str}'?你在外面的任何地方定义过“dic”吗?因为在dict理解中,它将没有任何参考 –