如何逐行对文本文件进行排序

时间:2019-05-13 22:28:35

标签: python python-3.x file sorting

我需要按升序对文本文件进行排序。文本文件的每一行都以索引开头,如下所示:

2       0       4         0d 07:00:38.0400009155273
3       0       4         0d 07:00:38.0400009155273
1       0       4         0d 07:00:38.0400009155273   

主意结果如下:

1       0       4         0d 07:00:38.0400009155273
2       0       4         0d 07:00:38.0400009155273
3       0       4         0d 07:00:38.0400009155273 

请注意,此文本文件具有+3百万行,每个元素自然被视为字符串。

一段时间以来,我一直在摸索这个问题,没有任何运气,所以我认为现在是时候咨询专家了。谢谢您的时间!

编辑:

我在Spyder IDE中将Windows OS与Python 3.7一起使用。该文件不是CSV,而是文本格式的文件,该文件以制表符分隔。有可能并非所有索引都存在。原谅新手,我没有很多编码经验。

6 个答案:

答案 0 :(得分:4)

fn = 'filename.txt'
sorted_fn = 'sorted_filename.txt'

with open(fn,'r') as first_file:
    rows = first_file.readlines()
    sorted_rows = sorted(rows, key=lambda x: int(x.split()[0]), reverse=False)
    with open(sorted_fn,'w') as second_file:
        for row in sorted_rows:
            second_file.write(row)

这应该适用于3+百万行的文本文件。使用int(x.split()[0])会将每一行中的第一项排序为整数

已编辑以删除close()语句

答案 1 :(得分:0)

我将通过将文件读取为几行,在空白处将它们分割,然后根据自定义键对它们进行排序来解决此问题;也就是说,如果您的文件名为“ foo.txt”:

with open("foo.txt") as file:
    lines = file.readlines()
    sorted(lines, key=lambda line: int(line.split()[0]))

此后,各行应包含按第一列排序的所有行。

但是,关于您的文件大小,我不知道这种方法的效果如何。也许您需要将文件的内容拆分为多个块,然后将其一一排序,然后再对这些块进行排序。

答案 2 :(得分:0)

我将使用简单的.split(' ')将数据格式化为如下所示的字典:

my_data = {
 2: ['0', '4', '0d', '07:00:38.0400009155273'],
 3: ['0', '4', '0d', '07:00:38.0400009155273'],
 1: ['0', '4', '0d', '07:00:38.0400009155273']
}

然后您可以像下面这样迭代(假设所有键都存在):

for i in range(1, max(list(my_data.keys())) + 1):
    pass # do some computation

另外,您可以选择一个特定的值,例如my_data[1]

为了能够以这种形式放置数据,我将使用以下脚本:

with open("foo.txt", "r") as file:
    in_data = file.readlines()

my_data = {}
for data in in_data:
    split_info = data.split(" ")
    useful_data = [item.strip() for item in split_info[1:] if item != ""]
    my_data.update({split_info[0]: useful_data})

for key in sorted(my_data.keys()):
    print("{}: {}".format(key, my_data[key]))

哪些印刷品:

  

1:['0','4','0d','07:00:38.0400009155273']

     

2:['0','4','0d','07:00:38.0400009155273']

     

3:['0','4','0d','07:00:38.0400009155273']

答案 3 :(得分:0)

使用熊猫它将极大地帮助您。假设文件是​​csv,请执行以下操作:

import pandas as pd
df = pd.read_csv('to/file', sep='\t', index='Name of column with index')  # Guessing that your file is tab separated
df.sort_index(inplace=True)

现在您有了一个数据框,其中包含您需要排序的所有信息。我建议您深入研究大熊猫,因为它确实可以帮助您。这是入门https://pandas.pydata.org/pandas-docs/stable/getting_started/10min.html

的链接

答案 4 :(得分:0)

这是您已经拥有的非常好的答案的编辑版本。编辑 在您了解有关编码的更多信息时可能会很有用。重点:

  • 编写程序时,通常最好使用少量示例进行编码 输入数据(例如,具有30行而不是300万行的文件): 您的程序将运行得更快;调试输出将越来越小 可读性以及其他一些原因。因此,与其硬编码 输入文件(或其他文件)的路径,将这些文件路径作为命令行 参数,使用sys.argv

    import sys
    
    in_path = sys.argv[1]
    out_path = sys.argv[2]
    
  • 如果您在内存中保存了大量数据(足以使您认为自己在 接近计算机的极限),请勿创建不需要的数据副本。对于 例如,要忽略前几行,请不要将原始行存储在 rows,然后使用rows[2:]获得所需的值:这将创建一个新的 清单。而是在您最初创建rows时添加条件逻辑( 该示例使用列表理解,但是您可以在常规中执行相同的操作 for循环)。而且,如果您需要对数据进行排序,请不要使用sorted(), 创建一个新列表;而是使用rows.sort()对列表进行排序。

    with open(in_path, 'r') as fh:
        rows = [line for i, line in enumerate(fh) if i > 1]
        rows.sort(key = lambda x: int(x.split(None, 1)[0]))
    
  • 没有理由将写作with块嵌套在阅读中 带块。如果您没有足够的理由来连接两个不同的任务 在程序中,将它们明确分开。这是最重要的 编写更好的软件的关键。

    with open(out_path, 'w') as fh:
        for r in rows:
            fh.write(r)
    

答案 5 :(得分:0)

一站式解决方案是使用一个文件句柄进行全部读取,排序和写入。感谢'r+'模式:

with open('your_file.txt', 'r+') as f:
    sorted_contents =  ''.join(sorted(f.readlines(), key = lambda x: int(x.split(' ')[0])))
    f.seek(0)
    f.truncate()
    f.write(sorted_contents)