【问题标题】:How can I add only non zero content from text file?如何从文本文件中仅添加非零内容?
【发布时间】:2025-11-23 15:20:02
【问题描述】:

我在文本文件中有以下类型的数据。

15  1  
23  0  
39 -1  
71 -1  
79  1  
95  1  
127 -2  
151  2  
183  1  
191 -1  
239  0  
247  3  

我想从文本文件创建一个二维列表,如下所示。我可以使用下面给出的代码来做到这一点,结果如下

[[15, 1.36896146582243],  
[23, 0.000000000000000],  
[39, 0.848993860380692],  
[71, 0.629227476540724],  
[79, 0.596517662620081],  
[95, 0.543970127117099],  
[127, 1.88189324753006],  
[151, 1.72587115688942],  
[183, 0.391932527534896],  
[191, 0.383636720228727]]  

但是我不想要所有条目,我只想要源文本文件第二列中非零条目的条目。例如我不想要条目

23  0
239 0

如何将条件语句添加到我的代码中。

with open("path.text") as file:
    R = [[int(x) for x in line.split()] for line in file]

【问题讨论】:

  • R = [[int(x) for x in line.split()] for line in file if '0' not in line.split()].
  • @Abdou - 不会捕获第一列中数字包含零的行。
  • @Abdou 不会捕获第一列中包含零的数字行是真的吗?
  • @Kumarm,我之前的评论版本确实如此。但我对其进行了编辑以确保这些行被捕获。所以上面的评论应该可以正常工作。
  • @Abdou 谢谢...

标签: arrays list python-3.x if-statement split


【解决方案1】:

pythonic 的解决方案是在列表推导中添加一个 if 语句

使用 open("path.text") 作为文件: R = [[int(x) for x in line.split()] for line in file if line[1] != '0']

【讨论】:

    【解决方案2】:

    没有必要把它硬塞到一个列表理解表达式中——在你的情况下它不会更快:

    result = []
    with open("path.text", "r") as f:
        for line in f:
            line = line.split()
            if len(line) < 2:  # just to make sure we have both columns
                continue
            column_2 = float(line[1])  # since, it appears, you have floats
            if column_2:
                result.append([int(line[0]), column_2])  # turn column 1 to int, too
    

    更新 - 基准时间 - 如果您将函数定义为彼此紧密匹配(因此没有上述浮动处理或验证):

    def f1():
        with open("path.text", "r") as f:
            return [[int(x) for x in line.split()] for line in f if '0' not in line.split()]
    
    def f2():
        result = []
        with open("path.text", "r") as f:
            for line in f:
                line = line.split()
                if line[1] != '0':
                    result.append([int(line[0]), int(line[1])])
        return result
    

    path.text 包含与 OP 和 assert f1() == f2() 传递相同的数据,这是我系统上的一些结果:

     Python 3.5.1, 64-bit
     f1() - 100,000 loops: 10.834s
     f2() - 100,000 loops: 9.9601s
    
     Python 2.7.11 64-bit
     f1() - 100,000 loops: 6.9243s
     f2() - 100,000 loops: 6.4012s
    

    其中大部分实际上是 I/O,相对而言,处理上的差异实际上要大得多。

    【讨论】:

    • 你说列表理解表达式在我的情况下不会更快,但你的方法需要更长的时间。
    • @Kumarm,过早优化是万恶之源。
    • 这是 97% 的情况之一,在这种情况下,您所做的任何优化都不会对总运行时间产生任何影响:使代码可读且结构良好,这样您就知道自己做了什么,并让I/O-bound 任务做它的事情。不用担心这里的性能。 @Kumarm
    • @AlexanderHuszagh - 我认为程序方法除了提供更多的控制和验证选择外,还更具可读性。显着加快(在处理方面)只是一个额外的好处。
    • @zwer,这就是我在争论的问题。在这种情况下,两者的性能也基本相同,因为 I/O 是房间里的大象。