努力锻炼档案

问题描述

我是python的初学者,试图解决文件练习。练习说:写一个函数,该函数采用文件名(包含单词行的文本文件),并返回每行中连续字符(如果存在)的字典。

每行都必须作为一个单词。换句话说,必须将一行中的字符分隔开来。

字典中的键代表重复的字符,值表示文件字符串中重复字符的次数

例如:文本文件中出现以下单词

casa a amalfi
azione estremizzata
ripasso organizzato

字典必须返回以下键和值:

{'a':1,'e':1,'z':2,'s':1,'o':1}

使用我编写的代码,我设法获得了这些期望值。但是,该词典还显示了一些不应显示的键和值。我只想要重复的字符以及每行中重复的次数

解决此问题,我尝试使用for循环删除值等于零的项目。但这是行不通的。取而代之的是,我收到一个运行时错误消息:字典在迭代期间更改了大小

这是我的代码

def conta_lettere (filename) : 
    
    dizionario = {}
    prev_char = None
    flag = 0
    with open(filename) as f:
        for riga in f:
            riga = ''.join(riga.split())
            for parola in riga:
                for lettera in parola:
                    if lettera not in dizionario:
                        dizionario[lettera] = 0
                if lettera == prev_char and flag !=0:
                    dizionario[lettera] +=1
                    flag = 0
                else:
                    flag = 1
                prev_char = lettera
        for chiave,valore in dizionario.items():
            if valore == 0:
                del dizionario[chiave] 
    return dizionario

任何帮助将不胜感激

这是我得到的输出

{'c': 0,'a': 1,'s': 1,'m': 0,'l': 0,'f': 0,'i': 0,'z': 2,'o': 1,'n': 0,'e': 1,'t': 0,'r': 0,'p': 0,'g': 0}

解决方法

由于您要逐行读取文件,因此建议您使用f.readline()。它将给出一个包含文件行的列表。

如果要从字符串中删除空格,将其转换为list并将其连接是一个不好的方法。您可以使用字符串替换方法:

riga = riga.replace(" ","")

这将删除所有空格。

要检查连续字母是否相同,请使用从索引0到最后一个-1的迭代器。

for i in range(0,len(line) - 1):

if(line[i] == line[i+1]):

您可以使用dict.keys()来获取字典中所有键的列表。因此,您可以使用简单的if(letter is in dict.keys())条件来检查字母是否在字典中,然后决定是插入字典还是增加counter的值。这样,您就不必在字典中添加任何不必要的字母作为键。

,

尝试一下:

def returner(file):
    dic = {}
    with open(file) as f:
        lines = f.read().split('\n')
        for line in lines:
            line = line.replace(' ','')
            count=1
            if len(line)>1:
                for i in range(1,len(line)):
                   if line[i-1]==line[i]:
                      count+=1
                   else :
                        if count > 1:
                            if line[i-1] in dic.keys():
                                dic[line[i-1]] += 1
                            else:
                                dic[line[i-1]] = 1
                        count=1
    return dic

returner('path/to/the/file')
,

自豪地解决了它:-)

from itertools import groupby 

s = "zioonne  estreemizzataa"

groups = groupby(s) 

result = [(label,sum(1 for _ in group)) for label,group in groups]

z = dict(result)

print(z) # check first success


delete = [] 

for key,val in z.items(): 

  if key == " " or val == 1: 

     delete.append(key) 

for i in delete: 

  del z[i] 

print(z) # check final success

输出

    {'z': 2,'i': 1,'a': 2,'o': 2,'n': 2,'e': 2,' ': 2,'s': 1,'t': 1,'r': 1,'m': 1}

{'z': 2,'e': 2}

最后一次dict被清除为仅打印相同连续字母的dict,即使其大于1也没有空格。

,

解决较大问题的方法是将其分解为较小的问题,然后依次解决每个问题(可能通过再次分解...)。在这种情况下: 1 /读取文件, 2 /准备要分析的数据, 3 /分析数据, 4 /报告结果。 这些代表着常见的数据科学序列。

1 /有两种读取文件的方法。是的,可以逐行读取(如在其他地方建议的那样),但是鉴于数据量很小,为什么不使用一个命令将整个文件读取为单个字符串呢?

看看这个字符串。除字母外,还有空格和一个/几个其他字符。注意:这些因操作系统而异!它/它们标记行的结尾。 (尽管您需要了解这个概念)

澄清:由于问题的措辞(“行”),我假设如果一行以与连续行中的第一个字母相同的字母结尾,则不算!!

2 /我们需要通过删除空格来“清理”数据。您是否知道“空字符”或“空字符串” /“空字符串”?有一个Python字符串函数,可以将一个字符串字符替换为另一个字符串字符。用“ nothing”代替空格,然后我们得到“ casaa ...”,因此是我们的第一个“ match”。无需担心行尾-它们不会与任何字母或其他字母匹配(但也可以根据需要将其删除)。

3 /要分析数据,请想象在纸上(或白板-一个出色的代码设计工具!)进行处理。将字符写在列中。现在,问题似乎在于将“此字符”与其下面的字符进行比较。但是,这引起了麻烦-在“底部”(没有“下一个字符”的地方)做什么?

相反,在第一个BUT的右侧创建第二个字符列,将第二个输入字符放在第二个列的顶部,然后跟着所有其他输入,并在底部添加“第一个字符” 。 (“第一个应该是最后一个”!)。现在,可以通过检查“跨”来形象地看到问题:左栏中的“ this”字符与右栏中的相应字符是否相同?

在Python中执行此操作时,您可以使用两个列表。但同样,您可以选择保留字符串(输入“到达”为字符串,是否要更改为字符列表“额外工作”?)

要处理两个字符串(或列表),大多数人发现有必要使Python的for循环像其他语言的for循环一样工作。不要这样做:Python是一个“ for each”循环,旨在依次访问集合的每个成员,而其他人的for循环旨在提供“指针”或“计数器”,即“沼泽” /“沼泽”错误的机会。

但是,这里需要同时处理两个集合(字符串是字符的集合!)。 Python提供了一个功能,使我们可以将两个字符串/列表/元组/ ...压缩在一起,就好像它们是一个实体一样-但是成对组织的(请参阅“串联”)。听起来有点熟?然后,这个结果(实际上是一种机制)可以传递给for(each)循环。

您要做的所有事情(别人说出来时听起来很容易!)是将“左字符”与“右字符”进行比较,如果匹配,则使用字典对其进行计数。 >

这里还有一个(另一个)问题:最简单的“计数”方法是使用“ + = 1”,只是在我们第一次计算字母时它假定为零值。有一些解决方案,例如defaultdicts,但是您也可以查看一下dictionary函数,如果字典键(此字母)已经存在,则该函数将获取一个值;如果字典键(此字母)已存在,则返回一个默认值(计数时为零)。

通过这种方式,您将不会拥有比必要的字典大得多的字典,并且没有零计数-然后您必须在下一步中删除/注销。

4 /报告结果仅是遍历计数器字典并报告字符倍频的问题。

鉴于这显然是学生作业,如果我给您答案作为代码,您将不会学。但是,“关键词”(上面)应该是显而易见的-您可以(应该)自己查找任何Python命令(https://docs.python.org/3/index.html)。同样,您需要熟悉的任何ComSc术语。请记住,如果打开Python交互式外壳或REPL,您将能够快速尝试“新”结构和构想!

因此,从我自己的实验/证明中计算出代码行(LoC): 1/2线 2/2线 3/3行作为循环 4/1或2或...行,具体取决于您希望输出的效果如何!

程序员可以通过提出一个简单的问题(在我看来,这可能是由于明显的“懒惰”而产生的)来进步:“当然,有一种更简单的方法可以做到这一点?”。查看Python提供的内置函数,并利用其功能(通过确保您的代码可读性来平衡),而不是尝试使其看起来像C,Java,...-或按照“生命周期建议” '“在您谈论(编写代码)之前/之前,请听(阅读手册)” ...

,

return dizionario替换为:

for key,val in dizionario.items():
    if val == 0:
        del dizionario[key]
return dizionario

让我知道这是否可行。

,

我理解您的示例,就像您想计算每行不带空格的最大字符增加量一样。如果字符与前一个字符相同,则可以通过将字典的“计数”增加1来更新它。这样,您只需要遍历字符串一次即可。

def count_max_repetitions(string):
    clean_string = "".join(string.split())
    dict_max_repetition = {x:1 for x in set(clean_string)}
    previous = ""
    for c in clean_string:
        if c == previous:
            dict_max_repetition[c] += 1
        previous = c
    return dict_max_repetition

string = "casa a amalfi"
count_max_repetitions(string)
#Out[27]: {'a': 3,'m': 1,'l': 1,'c': 1,'f': 1}

其他示例:

string = "azione estremizzata"
count_max_repetitions(string)
# Out[28]: 
# {'t': 1,#  'a': 1,#  'r': 1,#  'm': 1,#  'n': 1,#  'i': 1,#  's': 1,#  'z': 2,#  'o': 1,#  'e': 2}

string = "ripasso organizzato"
count_max_repetitions(string)
# Out[29]: 
# {'p': 1,#  't': 1,#  's': 2,#  'g': 1,#  'o': 2}