【问题标题】:Python - Read file and count repeated elementsPython - 读取文件并计算重复元素
【发布时间】:2017-10-08 08:35:49
【问题描述】:

我有一个包含如下数字列表的文本文件:
1
2 5 3
3 5
4
5
每个数字都是树的一个节点。当一行中有多个数字时,表示第一个数字与后面的数字相连。
1 后面没有任何数字,因此它没有链接任何数字.
2 有 3 和 5 链接到它。
3 有 5 链接到它并且它自己链接到 2。
4 没有任何数字链接。
5 没有任何数字链接,但它链接到 3 和 2。
由于 2、3 和 5 连接在一起,它们形成了一个组件。 1 和 4 没有链接,也没有数字链接,因此它们各自构成一个组件。
因此,总共有 3 个组件。
您将如何确定组件的数量? 我在 for 循环和条件语句方面遇到了困难。

def components(self):
    elm = 0
    with open('file.txt','r') as f:
        for line in f:
            comp = list(line)
            for x in comp:
                if comp[x] != comp[x+1]:
                    elm += 1
                else:
                    pass
    print(elm)

我尝试了上面的代码。但是,当我运行它时,我在函数执行中收到下一条消息:

 components missing 1 required positional argument: 'self'

可能有必要提一下,我正在处理课程,而且我对这件事几乎不陌生。

【问题讨论】:

  • 你的预期输出是什么?
  • self 是对函数类的引用。如果它不属于任何类,则需要从函数定义中删除 self。

标签: python file class for-loop


【解决方案1】:

您使用for-loops 以正确的方式进行此操作,但您似乎对loop 的内容感到有些困惑!如果我理解您想要正确实现的目标,我想我已经编写了代码以正常工作。

使用名为 file.txt 的 text 文件,其内容:

1
253
35
4
5

以下代码将创建components 中的list,然后print 在末尾有多少components:

components = []
with open("file.txt", "r") as f:
    for line in f:
        line = [int(i) for i in line.strip()]
        newComponent = True
        for comp in components:
            if not newComponent:
                break
            for ele in line:
                if ele in comp:
                    comp += line
                    newComponent = False
                    break
        components = [list(set(c)) for c in components]
        if newComponent:
            components.append(line)

print(len(components))

输出你想要的:

3

代码首先将text 文件打开到f。然后我们开始我们的第一个loop,它将遍历file 中的每个line。我们将这个line 转换为ints 的list 使用line.strip() 上的list-comprehension(.strip() 只是从末尾删除new-line char。

然后我们定义一个bool - newComponents - 初始化为True,因为我们假设这个line 将没有links。

接下来,我们通过 component 中的每个 component loop list components。我们在这里做的第一件事就是快速检查我们之前是否已经找到了一个component,这个line 是linked。如果有的话,我们就从这个loop 中取出break。

否则,如果我们还不是linked,我们会遍历line 中的每个element,并检查element 是否在component 中,我们目前是looping。如果是,我们把concatenate(加上+)我们的line放到那个component上,设置boolnewComponentflagfalse(因为我们有链接)和break出来这个loop,因为我们找到了link。

在此之后,components = [list(set(c)) for c in components] 行简单地遍历组件并从每个链接中删除 duplicates。例如,如果3 链接到2,并且我们之前刚刚将3 和5 添加到component,那么现在将有2 3s 在那个component - 重复.这一行只是删除了那些duplicates。严格来说,这行代码不是必需的,因为我们仍然会得到相同的结果,但我只是认为如果您以后想使用components,它会整理代码。

最后,如果没有找到links(newComponent 仍然是True),我们只需将整个line(因为它们是linked)附加到componentslist。

就是这样!我们将print() 的长度加上len() 放在最后,然后您就得到了结果。

希望对你有用!

更新

如果file.txt的内容是多位数字,可以用space分隔:

11
2 45
45 67
8
91

那么我们所要做的就是在list-comprehension 的末尾添加一个.split():

components = []
with open("file.txt", "r") as f:
    for line in f:
        line = [int(i) for i in line.strip().split(' ')]
        ...

这样做的目的是获取line 的string,而不是looping 通过string 中的每个char,我们在每个splitting 和string 中创建一个list space 和 iterate 通过它。为了证明这一点:

"123 456 789".split(" ")

给予:

["123", "456", "789"]

【讨论】:

  • 非常感谢。这完美地工作。我只是有一个问题。如果我使用多于一位的数字,需要进行哪些更改?
  • @Cotton-EyeJoe 我现在将其添加到答案中:)
  • @Cotton-EyeJoe 如果有用,请投票并接受:)
猜你喜欢
  • 1970-01-01
  • 2018-01-08
  • 2023-03-11
  • 1970-01-01
  • 2010-09-16
  • 2011-05-07
  • 2014-01-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多