2

所以这是我的代码:

with open('cipher.txt') as f:
  f = f.read().replace(' ', '')

new = []
for i in f:
    new = sorted([i + ' ' + str(f.count(i)) for i in f])
for o in new:
  print(o)

这是文本文件:

xli uymgo fvsar jsb

它应该使用每个字母并在使用它们的次数之前按字母顺序打印它们,但我不想要的是字母“s”(或任何.count()为2的字母)会重复两次,但我只想重复一次,我该怎么做?

这就是我得到的:

a 1
b 1
f 1
g 1
i 1
j 1
l 1
m 1
o 1
r 1
s 2
s 2
u 1
v 1
x 1
y 1

但这就是我想要的:

a 1
b 1
f 1
g 1
i 1
j 1
l 1
m 1
o 1
r 1
s 2
u 1
v 1
x 1
y 1
4

5 回答 5

1

您正在寻找的是collections.Counter()

from collections import Counter

with open('cipher.txt') as f:
    new = Counter(f.read().replace(' ', ''))

for letter, count in new.most_common():
   print(letter, count)

或者,或者按排序顺序打印字母:

for letter in sorted(new):
   print(letter, new[letter])

Counter.most_common()按计数对结果进行降序排序。sorted(new)另一方面,返回Counter字典键的排序列表,以便该版本更接近您尝试的输出。

相反,您的代码每次遇到f.count(i)每个字母时都会对其进行计数。您通常会使用字典来跟踪计数并避免使用以下内容的完整扫描:str.count()

counts = {}
for letter in f:
    counts[letter] = counts.get(letter, 0) + 1

for letter in sorted(new):
   print(letter, new[letter])
于 2013-09-02T09:05:50.437 回答
1

简单的方法是使用collections.Counter

from collections import Counter

s = "xli uymgo fvsar jsb"

for letter,count in Counter((i for i in s if i != ' ')).iteritems():
   print letter, count

要解决您的问题,您可以将列表转换为集合,或使用defaultdict. 这是 defaultdict 实现:

from collections import defaultdict

d = defaultdict(int)

for i in f:
    d[i] += 1

for k in sorted(d.keys()):
   print k, d[k]

如果您无法使用 Counter(适用于 2.7+),则 defaultdict 实现也很方便

于 2013-09-02T09:06:19.407 回答
1

为了计算每个字符在文本文件中出现的次数,您应该使用以下代码:

from collections import Counter

def get_char_count_from_file(file_path):
    with open(file_path) as f:
        return Counter(f.read())    

例子:

>>> get_char_count_from_file('C:/Python27/README.txt')
Counter({' ': 10634, 'e': 4067, 't': 3269, 'i': 2799, 'o': 2791, 'n': 2438, 's': 2307, 'a': 2283, 'r': 2183, 'l': 1848, 'h': 1469, 'u': 1278, '\n': 1229, 'd': 1225, 'c': 1196, '-': 1116, 'p': 969, 'm': 899, 'f': 846, 'y': 791, '.': 770, 'b': 697, 'g': 672, 'w': 488, ',': 408, '/': 326, 'k': 288, 'v': 286, 'T': 250, 'S': 223, 'P': 212, 'I': 198, 'C': 191, 'x': 177, '"': 176, ')': 176, '(': 162, '=': 125, ':': 119, 'O': 115, 'E': 108, 'D': 102, '2': 95, 'R': 95, 'A': 94, 'M': 94, '_': 89, 'N': 85, 'L': 84, "'": 84, '1': 78, 'X': 71, '0': 69, 'U': 65, 'G': 63, '4': 53, 'H': 53, 'B': 49, '3': 48, '+': 44, 'W': 42, 'F': 40, '5': 39, 'q': 36, 'Y': 35, '6': 31, 'z': 30, ';': 25, 'V': 22, 'j': 22, '8': 21, '9': 18, '$': 17, '@': 16, '7': 15, '<': 13, '>': 13, '\\': 11, '!': 11, '*': 10, '{': 8, '}': 8, 'K': 7, '`': 6, 'J': 6, '#': 5, 'Q': 5, '&': 4, '?': 3, 'Z': 3, '~': 3, '[': 2, '\t': 2, ']': 2})

你可以如何使用它:

>>> for k,v in sorted(Counter('xli uymgo fvsar jsb').items()):
    print k, v

  3
a 1
b 1
f 1
g 1
i 1
j 1
l 1
m 1
o 1
r 1
s 2
u 1
v 1
x 1
y 1
于 2013-09-02T09:06:36.737 回答
1

我会用collections.Counter这个:

import collections

s = 'xli uymgo fvsar jsb'
cnt = collections.Counter(s.replace(' ', ''))
for letter in sorted(cnt):
  print (letter, cnt[letter])

这打印出来

a 1
b 1
f 1
g 1
i 1
j 1
l 1
m 1
o 1
r 1
s 2
u 1
v 1
x 1
y 1
于 2013-09-02T09:07:31.093 回答
1
with open('cipher.txt') as f:
   f = f.read().replace(' ', '')

new = set()
for i in f:
    new = set(sorted([i + ' ' + str(f.count(i)) for i in f]))
for o in new:
print(o)    
于 2013-09-02T09:08:02.157 回答