在字符串中查找值出现时嵌套的for循环和字典

时间:2015-07-05 18:54:28

标签: python dictionary

我的任务是创建一个字典,其字符串是在字符串中找到的元素,其值计算每个值的出现次数。

实施例。

"abracadabra" → {'r': 2, 'd': 1, 'c': 1, 'b': 2, 'a': 5}

我背后有for循环逻辑:

xs = "hshhsf"
xsUnique = "".join(set(xs))

occurrences = []
freq = []

counter = 0

for i in range(len(xsUnique)):
    for x in range(len(xs)):
        if xsUnique[i] == xs[x]:
            occurrences.append(xs[x])
            counter += 1
    freq.append(counter)
    freq.append(xsUnique[i])
counter = 0 

这正是我想要它做的,除了列表而不是字典。如何才能使counter成为值,xsUnique[i]成为新词典中的关键?

3 个答案:

答案 0 :(得分:7)

最简单的方式是使用计数器:

>>> from collections import Counter
>>> Counter("abracadabra")
Counter({'a': 5, 'r': 2, 'b': 2, 'c': 1, 'd': 1})

如果您无法使用Python库,则可以使用默认值0的{​​{3}}来创建自己的计数器:

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

>>> count
{'a': 5, 'r': 2, 'b': 2, 'c': 1, 'd': 1}    

或者,您可以使用dict.get将计数器中的所有值设置为零,然后使用它:

>>> counter={}.fromkeys(s, 0)
>>> counter
{'a': 0, 'r': 0, 'b': 0, 'c': 0, 'd': 0}
>>> for c in s:
...    counter[c]+=1
... 
>>> counter
{'a': 5, 'r': 2, 'b': 2, 'c': 1, 'd': 1}

如果你真的想要最少的Pythonic ,也就是你在C中可能会做什么,你可能会这样做:

  1. 为设置为0
  2. 的所有可能的ascii值创建一个列表
  3. 循环遍历字符串并计算存在的字符
  4. 打印非零值
  5. 示例:

    ascii_counts=[0]*255
    s="abracadabra"
    
    for c in s:
        ascii_counts[ord(c)]+=1
    
    for i, e in enumerate(ascii_counts):
        if e:
            print chr(i), e 
    

    打印:

    a 5
    b 2
    c 1
    d 1
    r 2
    

    然而,由于您需要dict.fromkeys()列表条目,因此无法扩展以与Unicode一起使用...

答案 1 :(得分:1)

您可以使用zip功能将列表转换为字典:

>>> dict(zip(freq[1::2],freq[0::2]))
{'h': 3, 's': 2, 'f': 1}

但是,我建议使用collections.Counter

作为更加pythonic和相当优化的方式
>>> from collections import Counter
>>> Counter("hshhsf")
Counter({'h': 3, 's': 2, 'f': 1})

正如你所说,你不想导入任何模块,你可以使用dict.setdefault方法和一个简单的循环来使用字典:

>>> d={}
>>> for i in xs:
...    d[i]=d.setdefault(i,0)+1
... 
>>> d
{'h': 3, 's': 2, 'f': 1}

答案 2 :(得分:1)

我猜这是为什么你使用两个forloops的$user = JWTAuth::parseToken()->toUser(); 原因? 无论如何,还有一些不同的解决方案:

learning

输出

# Method 1
xs = 'hshhsf'
xsUnique = ''.join(set(xs))

freq1 = {}
for i in range(len(xsUnique)):
    for x in range(len(xs)):
        if xsUnique[i] == xs[x]:
            if xs[x] in freq1:
                freq1[xs[x]] += 1
            else:
                freq1[xs[x]] = 1 # Introduce a new key, value pair

# Method 2
# Or use a defaultdict that auto initialize new values in a dictionary
# https://docs.python.org/2/library/collections.html#collections.defaultdict

from collections import defaultdict

freq2 = defaultdict(int) # new values initialize to 0
for i in range(len(xsUnique)):
    for x in range(len(xs)):
        if xsUnique[i] == xs[x]:
            # no need to check if xs[x] is in the dict because 
            # defaultdict(int) will set any new key to zero, then
            # preforms it's operation.
            freq2[xs[x]] += 1


# I don't understand why your using 2 forloops though

# Method 3
string = 'hshhsf' # the variable name `xs` confuses me, sorry

freq3 = defaultdict(int)
for char in string:
    freq3[char] += 1

# Method 4
freq4 = {}
for char in string:
    if char in freq4:
        freq4[char] += 1
    else:
        freq4[char] = 1



print 'freq1: %r\n' % freq1
print 'freq2: %r\n' % freq2
print 'freq3: %r\n' % freq3
print 'freq4: %r\n' % freq4

print '\nDo all the dictionaries equal each other as they stand?'
print 'Answer: %r\n\n'  % (freq1 == freq2 and freq1 == freq3 and freq1 == freq4)

# convert the defaultdict's to a dict for consistency
freq2 = dict(freq2)
freq3 = dict(freq3)

print 'freq1: %r' % freq2
print 'freq2: %r' % freq2
print 'freq3: %r' % freq3
print 'freq4: %r' % freq4

或者像dawg所述,使用集合标准库中的Counter

反文件

https://docs.python.org/2/library/collections.html#collections.Counter

defaultdict docs

https://docs.python.org/2/library/collections.html#collections.defaultdict

馆藏文献

https://docs.python.org/2/library/collections.html