【问题标题】:Python removing duplicates and saving the resultPython删除重复项并保存结果
【发布时间】:2014-08-01 20:45:54
【问题描述】:

我正在尝试删除 3 列制表符分隔的 txt 文件的重复项,但只要前两列是重复的,那么即使两者的第 3 列不同,也应该将其删除。

from operator import itemgetter
import sys

input = sys.argv[1]
output = sys.argv[2]

#Pass any column number you want, note that indexing starts at 0
ig = itemgetter(0,1) 
seen = set()
data = []
for line in input.splitlines():
    key = ig(line.split())
    if key not in seen:
        data.append(line)
        seen.add(key)
        file = open(output, "w")
        file.write(data)
        file.close()

首先,我得到错误

key = ig(line.split())
IndexError: list index out of range

另外,我看不到如何将结果保存到 output.txt

人们说保存到 output.txt 是一件非常基本的事情。但是没有教程有帮助。

我尝试了使用编解码器的方法,使用 with 的方法,使用 file.write(data) 的方法,但都没有帮助。

我可以很容易地学习 MatLab。在线教程非常棒,一系列谷歌搜索总是有很大帮助。

但我还没有找到有用的 Python 教程。这显然是因为我是一个完全的新手。对于像我这样的新手来说,1) 全面性和 2) 大量示例 3) 逐行解释的最佳教程是什么?

为什么上面的代码会导致错误而不保存结果?

【问题讨论】:

  • 我强烈建议您使用print 语句来显示变量的内容,以确保它们包含您认为的内容。

标签: python


【解决方案1】:
  • 我假设由于您将input 分配给第一个命令行参数,input = sys.argv[1]output 分配给第二个,您打算将它们作为您的输入和输出文件名。但是您永远不会为输入数据打开任何文件,因此您在文件 name 上调用 .splitlines(),而不是在文件内容上。

  • 接下来,splitlines() 无论如何都是错误的方法。 To iterate over a file line-by-line, simply use for line in f,其中f 是一个打开的文件。这些行将在行尾包含换行符,因此如果它不应该是第三列数据的一部分,则需要将其剥离。

  • 然后您将在循环中打开和关闭文件,这意味着您将尝试在每次迭代时将data 的全部内容写入文件,从而有效地覆盖之前写入文件的任何数据。因此我把那个块移出了循环。

  • It's good practice to use the with statement for opening fileswith open(out_fn, "w") as outfile 将打开名为out_fn 的文件并将打开的文件分配给outfile,并在您退出该缩进块时立即为您关闭它。

  • input 是 Python 中的内置函数。因此,我重命名了您的变量,因此不会隐藏任何内置名称。

  • 您正尝试将data 直接写入输出文件。这不起作用,因为data 是行的list。您需要先join 这些行,以便在将它们写入文件之前再次将它们转换为单个字符串。

以下是解决所有这些问题的代码:

from operator import itemgetter
import sys


in_fn = sys.argv[1]
out_fn = sys.argv[2]

getkey = itemgetter(0, 1)
seen = set()
data = []

with open(in_fn, 'r') as infile:
    for line in infile:
        line = line.strip()
        key = getkey(line.split())
        if key not in seen:
            data.append(line)
            seen.add(key)

with open(out_fn, "w") as outfile:
    outfile.write('\n'.join(data))

【讨论】:

    【解决方案2】:

    为什么上面的代码会报错?
    因为您尚未打开文件,所以您尝试使用字符串 input.txt 而不是文件。然后,当您尝试访问您的项目时,您会得到一个超出范围的列表索引,因为line.split() 返回['input.txt']。 如何解决这个问题:打开文件然后使用它,而不是使用它的名称。 例如,你可以这样做(我尽量靠近你的代码)

    input = sys.argv[1]
    infile = open(input, 'r')
    (...)
    lines = infile.readlines()
    infile.close()
    for line in lines:
        (...)
    

    为什么没有保存结果?
    因为您正在循环内打开/关闭文件。您需要做的是在您退出循环后写入数据。此外,您不能直接将列表写入文件。因此,您需要执行以下操作(在循环之外):

    outfile = open(output, "w")
    for item in data:
      outfile.write(item)
    outfile.close()
    

    一起
    还有其他读/写文件的方法,it is pretty well documented on the internet 但我尽量靠近你的代码,以便你更好地理解它有什么问题

    from operator import itemgetter
    import sys
    
    input = sys.argv[1]
    infile = open(input, 'r')
    output = sys.argv[2]
    
    #Pass any column number you want, note that indexing starts at 0
    ig = itemgetter(0,1)
    seen = set()
    data = []
    lines = infile.readlines()
    infile.close()
    for line in lines:
        print line
        key = ig(line.split())
        if key not in seen:
            data.append(line)
            seen.add(key)
    
    print data
    outfile = open(output, "w")
    for item in data:
      outfile.write(item)
    outfile.close()
    

    PS:它似乎产生了你需要的结果Python to remove duplicates using only some, not all, columns

    【讨论】:

    • 非常感谢。但是,该程序似乎将制表符和空格视为分隔符。这可以只考虑制表符作为分隔符吗?也许我们需要像 x = line.split("\t") 这样的东西? (但在哪里以及如何?)我上传了图片以显示问题所在。 drive.google.com/file/d/0B1sEqo7wNB1-QXlRWFd4OVJRLWM/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-04-25
    • 1970-01-01
    • 2021-07-26
    • 2015-03-19
    • 1970-01-01
    • 2014-06-08
    • 1970-01-01
    相关资源
    最近更新 更多