【问题标题】:Best way to sort txt file using csv tools in python在 python 中使用 csv 工具对 txt 文件进行排序的最佳方法
【发布时间】:2017-12-26 13:25:57
【问题描述】:

我有以下代码,并试图以最简单的方法对文件内容进行排序。

import csv
import operator

#==========Search by ID number. Return Just the Name Fields for the Student
with open("studentinfo.txt","r") as f:
  studentfileReader=csv.reader(f)
  id=input("Enter Id:")
  for row in studentfileReader:
    for field in row:
      if field==id:
        currentindex=row.index(id)
        print(row[currentindex+1]+" "+row[currentindex+2])

#=========Sort by Last Name
with open("studentinfo.txt","r") as f:
  studentfileReader=csv.reader(f)
  sortedlist=sorted(f,key=operator.itemgetter(0),reverse=True)
  print(sortedlist)

我知道各种可能的解决方案,但不能完全让它们正常运行,并且出于教学/学习目的,我对最简单有效且解释清楚的解决方案感兴趣。

研究包括: ****进口运营商**** sortedlist = sorted(reader, key=operator.itemgetter(3), reverse=True)

或使用 lambda sortedlist = sorted(reader, key=lambda row: row[3], reverse=True)

对于答案,如果有人可以发布完整的工作解决方案,我将不胜感激,显示按 LAST NAME 和 ID Number 排序,以说明两个不同的示例。答案的扩展是在这个特定示例中展示如何按多个值排序:

完整代码清单:

https://repl.it/Jau3/3

文件内容

002,Ash,Smith,Test1:20,Test2:20,Test3:100003
004,Grace,Asha,Test1:33,Test2:54,Test3:23
005,Cat,Zelch,Test1:66,Test2:22,Test3:11
001,Joe,Bloggs,Test1:99,Test2:100,Test3:1
003,Jonathan,Peter,Test1:99,Test2:33,Test3:44

【问题讨论】:

    标签: python file csv sorting


    【解决方案1】:

    使用导入运算符,就像您所做的那样,以及一种可能的解决方案:注意 - 理想情况下,您需要一个标题来区分您想要排序的内容(假设用户想要明确指定)

    import csv
    import operator
    ifile =open('myfile.csv', 'rb')
    infile = csv.reader(ifile)
    # Note that if you have a header, this is the header line
    infields = infile.next()
    startindex = infields.index('Desired Header')
    # Here you are creating the sorted list
    sortedlist = sorted(infile, key=operator.itemgetter(startindex), reverse=True)
    ifile.close
    # open the output file - it can be the same as the input file
    ofile = open('myoutput.csv, 'wb')
    outfile.writerow(infields)
    for row in sortedlist:
      outfile.writerow(row)
    ofile.close()
    

    【讨论】:

    • 这很有用 - 在添加标题方面,我需要研究一下。您能否使用我现有的原始代码发布完整的解决方案。
    【解决方案2】:

    您可以使用lambda 函数按csv 阅读器返回的列表中的任意键进行排序,例如,按姓氏(第三列):

    with open("studentinfo.txt", "r") as f:
        reader = csv.reader(f)
        sorted_list = list(reader)  # turn the reader iterator into a list
        sorted_list.sort(key=lambda x: x[2])  # use the third column as a sorting key
        print("\n".join(str(row) for row in sorted_list))  # prettier print
    

    或按 ID(第一列):

    with open("studentinfo.txt", "r") as f:
        reader = csv.reader(f)
        sorted_list = list(reader)  # turn the reader iterator into a list
        sorted_list.sort(key=lambda x: x[0])  # the first column as a sorting key, can be omitted
        print("\n".join(str(row) for row in sorted_list))  # prettier print
    

    或者通过两个键:

    with open("studentinfo.txt", "r") as f:
        reader = csv.reader(f)
        sorted_list = list(reader)  # turn the reader iterator into a list
        sorted_list.sort(key=lambda x: (x[3], x[4]))  # use fourth and fifth column
        print("\n".join(str(row) for row in sorted_list))  # prettier print
    

    您可以将reverse=True 添加到list.sort() 调用以进行降序排序。

    ADDENUM - 如果你真的不想使用 lambda(为什么?),你可以定义一个 item-getter 函数(或者只使用为此目的而存在的operator.itemgetter)并通过list.sort() 电话,例如:

    def get_third_column(x):
        return x[2]
    
    with open("studentinfo.txt", "r") as f:
        reader = csv.reader(f)
        sorted_list = list(reader)  # turn the reader iterator into a list
        sorted_list.sort(key=get_third_column)  # use the third column as a sorting key
        print("\n".join(str(row) for row in sorted_list))  # prettier print
    

    【讨论】:

    • 你能在没有 lambda 的情况下提出一些建议吗(对于教初学者,有没有办法在不引入任何外部内容的情况下做到这一点)。
    • @MissComputing - lambda 函数不是外部的,它们是 Python 语言的重要组成部分。如果您愿意,可以将它们替换为已定义的函数。我将在上面添加一个示例。
    • 谢谢你——我从中学到了。虽然,一个函数又增加了不必要的复杂性。想想:完全初学者(儿童!)的教学法
    【解决方案3】:

    一个紧凑、简单的读取->排序->写入解决方案:

    import csv
    import operator
    
    with open("input.csv") as fh:
        reader = csv.reader(fh)
        rows = sorted(reader, key=operator.itemgetter(0), reverse=True)
    
    with open("output.csv", "w") as fh:
        csv.writer(fh).writerows(rows)
    

    要在控制台上打印而不是写入文件, 你可以使用sys.stdout作为文件句柄:

    import sys
    
    with sys.stdout as fh:
        csv.writer(fh).writerows(rows)
    

    operator.itemgetter(0) 确定要排序的字段。 第 0 个字段是 id。 要按姓氏排序,请使用operator.itemgetter(2), 因为姓是第三列。

    要按多个字段排序,您需要使用 lambda,例如先按姓再按名字排序:

        rows = sorted(reader, key=lambda x: (x[2], x[1]), reverse=True)
    

    排序前的代码,你要求用户输入一个ID, 也可以改进:

    • 如果您知道 id 字段是第一个字段,则无需遍历每个字段
    • id 隐藏了 Python 中的一个内置函数,所以不建议作为变量使用

    你可以这样写:

    with open("studentinfo.txt") as fh:
        reader = csv.reader(fh)
        student_id = input("Enter Id:")
        for row in reader:
            if row[0] == student_id:
                print(row[1] + " " + row[2])
    

    【讨论】:

    • 我喜欢第一个的外观,因为我不需要多个值排序,这就是为什么最简单的解决方案就是我所追求的。但是,您是否可以使用我的原始代码作为工作答案发布解决方案
    • @MissComputing 你的意思是包括代码的第一部分,你要求一个 ID 并打印一个名字吗?或者您的“原始代码作为工作答案”是什么意思?
    • @MissComputing 我在答案中添加了更多细节。如果这仍然不是您想要的,请解释
    • 只是排序部分......但使用我的变量和现有结构。就像您使用 fh 等一样,因此只需使用我的原始代码,并将您的答案/解决方案放入其中。
    • @MissComputing 根据您收到的解释,您应该能够对您的解决方案进行必要的调整以使其正常工作。 (其实只需要修复一行:sortedlist=sorted(studentfileReader,key=operator.itemgetter(0),reverse=True)
    猜你喜欢
    • 2015-06-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-07
    • 1970-01-01
    • 2017-06-23
    • 1970-01-01
    相关资源
    最近更新 更多