【问题标题】:Iterate over multiple files and count multiple strings遍历多个文件并计算多个字符串
【发布时间】:2023-03-20 11:35:02
【问题描述】:

我想编写一个代码来打开多个文本文件并计算每个文件中预定义字符串出现的次数。我想要的输出可以是文件中每个字符串出现的总和的列表。

我想要的字符串是字典的值。

例如:

mi = { "key1": "string1", "key2": "string2", and so on..." }

为了打开一个独特的文件并实现我想要的计数,我得到了代码。检查以下:

mi = {} #my dictionary
data = open("test.txt", "r").read()
import collections 
od_mi = collections.OrderedDict(sorted(mi.items()))
count_occur = list()

for value in od_mi.values():
    count = data.count(value)
    count_occur.append(count)

lista_keys = []   
for key in od_mi.keys():
    lista_keys.append(key)

dic_final = dict(zip(lista_keys, count_occur))
od_mi_final = collections.OrderedDict(sorted(dic_final.items()))

print(od_mi_final) #A final dictionary with keys and values with the count of how many times each string occur. 

我的下一个目标是对多个文件做同样的事情。我有一组根据模式命名的文本文件,例如“ABC 01.2015.txt ;ABC 02.2015.txt ...”。

我制作了 3 个文本文件作为测试文件,在每个文件中,每个字符串出现一次。因此,在我的测试运行中,我想要的输出是每个字符串的计数为 3。

mi = {}
import collections
od_mi = collections.OrderedDict(sorted(mi.items()))
for i in range(2,5):
for value in od_mi.values():
    x = "ABC" + " " + str(i) +".2015.txt"
    data = open(x, "r").read()
    contar = data.count(value)
    count_occur.append(contar)

 print(count_occur)

输出:

[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]

我意识到我的代码在每次进入循环时都会覆盖计数。因此,我该如何解决这个问题?

【问题讨论】:

    标签: python file loops counter


    【解决方案1】:

    您应该使用Counter 来简化您的代码:

    from collections import Counter
    
    mi = {'key1': 'string1', 'key2': 'string2'}
    count_occur = []
    with open("test.txt", "r") as data_file:
        for data in data_file:
            count_occur.extend([d for d in data.split() if d in mi.values()])
    
    print Counter(count_occur)
    

    然后,要在多个文件上处理它,只需在文件列表上循环,例如:

    from collections import Counter
    
    count_occur = []
    mi = {'key1': 'string1', 'key2': 'string2'}
    files = ["ABC" + " " + str(i) +".2015.txt" for i in range(2,5)]
    
    for file_c in files:
        with open(file_c, "r") as data_file:
            for data in data_file:
                count_occur.extend([d for d in data.split() if d in mi.values()])
    
    print Counter(count_occur)
    

    【讨论】:

    • 您好,谢谢您的回答。在每种情况下,输出都是:Counter()。我相信函数输出中没有数字...
    • 这意味着'count_occur'是空的,你的'mi'字典是否充满了请求的字符串?
    • 是的,先生!我的字典充满了所有的字符串。我检查了 count_occur 列表里面是否有东西并且它是空的。
    • 由于某种原因,代码的输出与以前相同。
    • 只是一些细节,我的测试文件是用 UTF-8 编码的,里面有特殊字符。
    【解决方案2】:

    从你的 mi dict 中的值创建一个 Counter,然后使用新的 Counter dict 键和每行拆分词之间的交集:

    mi = { "key1": "string1", "key2": "string2"}
    
    
    import collections
    from collections import Counter
    counts = Counter(dict.fromkeys(mi.values(), 0))
    for fle in list_of_file_names:
        with open(fle) as f:
            for words in map(str.split, f):
                counts.update(counts.viewkeys() & words)
    print(counts)
    

    如果您正在寻找完全匹配并且您有多个单词短语要查找,那么您最好的选择是带有单词边界的正则表达式:

    from collections import Counter
    
    import re
    
    patt = re.compile("|".join([r"\b{}\b".format(v) for v in mi.values()]))
    for fle in list_of_file_names:
        with open(fle) as f:
            for line in f:
                counts.update(patt.findall(line))
    print(counts)
    

    您可能会发现在 f.read() 上调用正则表达式,假设文件内容适合内存:

    with open(fle) as f:
         counts.update(patt.findall(f.read()))
    

    常规的 re 模块不适用于重叠匹配,如果你 pip install [regex][1] 设置重叠标志后将捕获重叠匹配:

    import regex
    import collections
    from collections import Counter
    counts = Counter(dict.fromkeys(mi.values(), 0))
    
    patt = regex.compile("|".join([r"\b{}\b".format(v) for v in mi.values()]))
    for fle in list_of_files:
        with open(fle) as f:
            for line in f:
                counts.update(patt.findall(line, overlapped=True))
    print(counts)
    

    如果我们稍微改变一下你的例子,你就会发现不同:

    In [30]: s = "O rótulo contém informações conflitantes sobre a natureza mineral e sintética."
    
    In [31]: mi =  {"RTL. 10": "conflitantes sobre", "RTL. 11": "sobre"}
    In [32]: patt = re.compile("|".join([r"\b{}\b".format(v) for v in mi.values()])) 
    In [33]: patt.findall(s)
    Out[33]: ['conflitantes sobre']
    
    In [34]: patt = regex.compile("|".join([r"\b{}\b".format(v) for v in mi.values()]))
    
    In [35]: patt.findall(s,overlapped=True)
    Out[35]: ['conflitantes sobre', 'sobre']
    

    【讨论】:

    • 你好,帕德莱克!谢谢您的帮助!我用我原来的字典做了一个测试,它有很多带有特殊字符的字符串,由于某种原因不起作用。最终输出对他们来说是零。但我重新制作了我的测试文件,只搜索没有特殊字符的字符串,你的代码效果很好。你能帮我解决我原来的字符串集的问题吗?
    • 您能否提供一个文件内容的小样本以及您的 dict 值中的内容?还有什么版本的python?
    • 我使用 Canopy,它使用 ' Python 2.7.10 | 64 位 | (默认,2015 年 10 月 21 日,17:08:47)[MSC v.1500 64 位 (AMD64)]'。 some examples = > "RTL. 10": "O rótulo apresentado está ilegível/incompleto.", "RTL. 11": "O rótulo contém informações conflitantes sobre a natureza Mineral e sintética."
    • 您是否真的在寻找不仅仅是单个单词?
    • 啊,好吧,那是一个非常不同的故事,你也在匹配子字符串,即foo将匹配foobar
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-12-15
    • 1970-01-01
    • 2018-01-16
    • 2015-03-26
    • 2013-05-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多