将文件转换为字典以计算出现次数

时间:2018-06-16 16:51:08

标签: python

我有一个文件,其内容如下所示:

eng word1
eng word2
eng word3
ita word1
ita word2
fra word1
...

我想计算每种语言中每个单词的出现次数。为此,我想在dict中读取文件。 这是我的尝试:

data = open('file', 'r', encoding='utf8')
for line in data:
    lang = line[:3]
    ipa_string = line[3:]
    lang_and_string_dict[lang] = []
    lang_and_string_dict[lang].append(ipa_string)
print(lang_and_string_dict)

这给了我一个带有正确键的词典,但只有最后一个词例如英语:

{'eng':[word1]}

4 个答案:

答案 0 :(得分:3)

每次将空列表指定为值

data = open('file', 'r', encoding='utf8')
for line in data:
    lang = line[:3]
    ipa_string = line[3:]
    lang_and_string_dict[lang] = []
    lang_and_string_dict[lang].append(ipa_string)
print(lang_and_string_dict)

因此,包含上一个事件的旧列表将丢失。如果不存在这样的元素,您应该只创建一个列表,例如:

data = open('file', 'r', encoding='utf8')
for line in data:
    lang = line[:3]
    ipa_string = line[3:]
    if lang not in lang_and_string_dict:
        lang_and_string_dict[lang] = []
    lang_and_string_dict[lang].append(ipa_string)
print(lang_and_string_dict)

由于此模式相当常见,您也可以使用defaultdict

from collection import defaultdict

lang_and_string_dict = defaultdict(list)
with open('file', 'r', encoding='utf8') as data:
    for line in data:
        lang = line[:3]
        ipa_string = line[3:]
    lang_and_string_dict[lang].append(ipa_string)
print(lang_and_string_dict)

defaultdictdict的子类,它使用工厂(此处为list)以防密钥丢失。因此,每次查询不在字典中的键时,我们构造list

您稍后可以使用defaultdict将此类dict转换为dict(lang_and_string_dict)

此外,如果您使用open(..)个文件,最好使用with块执行此操作。因为如果出现例外,那么文件仍然正确关闭。

答案 1 :(得分:3)

使用dict的简单方法,其中键是lang,值是单词出现的计数器

from collections import Counter, defaultdict

lang_and_string_dict = defaultdict(Counter)
with open('file', 'r', encoding='utf8') as f:
    for line in f:
        lang, word = line.split()
        lang_and_string_dict[lang].update([word])


print(lang_and_string_dict)

输出

defaultdict(<class 'collections.Counter'>, {'eng': Counter({'word1': 1, 'word2': 1, 'word3': 1}), 'ita': Counter({'word1': 1, 'word2': 1}), 'fra': Counter({'word1': 1})})

请注意如果文件中的行不是精确的lang, word = line.split()格式,则行lang word会导致错误或意外行为,例外情况和建议检查

答案 2 :(得分:1)

另一种解决方法是使用collections.Counter。它返回每个类别下的单词数量:

from collections import Counter

words = []
with open('file') as f:
    for line in f:
        words.append(line.split()[0])

print(Counter(words))
# Counter({'eng': 3, 'ita': 2, 'fra': 1})

要计算每个类别下每个单词的计数:

from collections import Counter

words = []
with open('file.txt') as f:
    lines = f.readlines()
    prev = lines[0].split()[0]
    for line in lines:
        splitted = line.split()
        if splitted[0] != prev:
            print('{} -> {}'.format(prev, Counter(words)))
            prev = splitted[0]
            words = []
        words.append(line.split()[1])

print('{} -> {}'.format(prev, Counter(words)))

# eng -> Counter({'word1': 1, 'word2': 1, 'word3': 1})
# ita -> Counter({'word1': 1, 'word2': 1})                         
# fra -> Counter({'word1': 1})                            

答案 3 :(得分:0)

与@ shahaf类似的解决方案,但使用defaultdict(int)代替Counter

我还使用csv.DictReader来使逻辑更清晰。

from collections import defaultdict
import csv
from io import StringIO

mystr = StringIO("""eng word1
eng word2
eng word3
eng word1
ita word1
ita word2
ita word2
fra word1""")

d = defaultdict(lambda: defaultdict(int))

# replace mystr with open('file.csv', 'r')
with mystr as fin:
    reader = csv.DictReader(fin, delimiter=' ', fieldnames=['language', 'word'])
    for line in reader:
        d[line['language']][line['word']] += 1

print(d)

defaultdict({'eng': defaultdict(int, {'word1': 2, 'word2': 1, 'word3': 1}),
             'ita': defaultdict(int, {'word1': 1, 'word2': 2}),
             'fra': defaultdict(int, {'word1': 1})})