在Python上按关键字对txt中的行进行排序

2024-05-29 03:01:28 发布

您现在位置:Python中文网/ 问答频道 /正文

我在python上遇到了一个问题:我想在下面所需的输出中对.txt进行排序 但我没有得到这个输出,而是得到了错误的输出,第一行和第二行连接在一起,文件末尾是空行 为什么会这样

提前谢谢你的帮助

输入文件:

https://markus.rmart.ru/wormix_mm/preloader/
https://markus.rmart.ru/wormix_ok/preloader/
https://markus.rmart.ru/engine/preloader/

期望输出:

https://markus.rmart.ru/engine/preloader/
https://markus.rmart.ru/wormix_mm/preloader/
https://markus.rmart.ru/wormix_ok/preloader/

实际产出:

https://markus.rmart.ru/engine/preloader/https://markus.rmart.ru/wormix_mm/preloader/
https://markus.rmart.ru/wormix_ok/preloader/

代码:

test_out = open('./test_out999.txt', "w")

def my_sort(line):
    social_folders = {'engine': 1,
                    'wormix_mm': 2,
                    'wormix_ok': 3}
    line_fields = line.strip().split("/")
    social = line_fields[3]
    print(line_fields[3])
    return social_folders[social]

testsortf = open('./testsort.txt')
contents = testsortf.readlines()

contents.sort(key=my_sort)

for line in contents:
        test_out.write(line)

testsortf.close()
test_out.close()

但是,当我删除最后一个带有行.rstrip('\n')的“\n”并手动添加“\n”时,我会获取此输出(在文件末尾有不需要的空行):

https://markus.rmart.ru/engine/preloader/
https://markus.rmart.ru/wormix_mm/preloader/
https://markus.rmart.ru/wormix_ok/preloader/

小补丁:

test_out.write(line.rstrip('\n') + "\n")

那么,为什么会发生这种情况?如何让我获得期望的输出

如果有人能帮我解决这个问题,接下来。。。如何获得此输出

First:
https://markus.rmart.ru/engine/preloader/

Second:
https://markus.rmart.ru/wormix_mm/preloader/

Third:
https://markus.rmart.ru/wormix_ok/preloader/

Tags: 文件httpstesttxtrulinesocialok
2条回答

\n添加到每一行时,\n也添加到最后一行。除了换行符之外的每一行上,都会在之前创建的换行符上写入一些内容-但是,在最后一行,该换行符中没有写入任何内容,将其留空。以下是一个例子:

迭代1:

https://markus.rmart.ru/wormix_mm/preloader/

迭代2:

https://markus.rmart.ru/wormix_mm/preloader/
https://markus.rmart.ru/wormix_ok/preloader/

请注意,我们在交互1中创建的新行现在包含文本。如果没有换行符,它将如下所示:

https://markus.rmart.ru/wormix_mm/preloader/https://markus.rmart.ru/wormix_ok/preloader/

因为文本是从文件末尾写入的

最后,迭代3:

https://markus.rmart.ru/engine/preloader/
https://markus.rmart.ru/wormix_mm/preloader/
https://markus.rmart.ru/wormix_ok/preloader/

如您所见,迭代3之后没有写入任何内容,最后一行留空

为了解决这个问题,您需要做一个简单的检查,看看该行当前是否是最后一行(将for line in contentsfor循环替换为以下内容):

for i in range(len(contents)):
    test_out.write(line.rstrip('\n'))
    if i < len(contents) - 1:
        test_out.write("\n")

为了做你想做的事(即FirstSecondThird),你可以有一个充满这些单词的列表:

num_to_word = ["First", "Second", "Third"]
for i in range(len(contents)):
    test_out.write(num_to_word[i] + ":\n")
    test_out.write(line.rstrip('\n'))
    if i < len(contents) - 1:
        test_out.write("\n\n") # Two newlines to add a line in between

(我还没有测试过,如果不行请告诉我)

您意想不到的:

https://markus.rmart.ru/engine/preloader/https://markus.rmart.ru/wormix_mm/preloader/
https://markus.rmart.ru/wormix_ok/preloader/

是因为输入文件的最后一行没有换行符。
因此,如果我们将换行标记为

Input file:

https://markus.rmart.ru/wormix_mm/preloader/△
https://markus.rmart.ru/wormix_ok/preloader/△
https://markus.rmart.ru/engine/preloader/

因此content的2个元素有\n后缀,而1没有,导致了不同的行为。
简单的解决方法是,不要每次都添加额外的换行符,而只添加到最后一行:

contents = testsortf.readlines()
contents[-1] = f'{contents[-1]}\n'

如果contents可能为空:

contents = testsortf.readlines()
if contents:
    contents[-1] = f'{contents[-1]}\n'

现在我们有了代码:

test_out = open('...', "w")

def my_sort(line):
    social_folders = {'engine': 1,
                    'wormix_mm': 2,
                    'wormix_ok': 3}
    line_fields = line.strip().split("/")
    social = line_fields[3]
    print(line_fields[3])
    return social_folders[social]

testsortf = open('...')
contents = testsortf.readlines()
contents[-1] = f'{contents[-1]}\n'
contents.sort(key=my_sort)
for line in contents:
    test_out.write(line)

testsortf.close()
test_out.close()

为了添加FirstSecond等,首先添加一个tuple,例如

numbers = 'First', 'Second', 'Third'

然后使用方便的enumerate()

test_out = open('./test_out999.txt', "w")

def my_sort(line):
    social_folders = {'engine': 1,
                    'wormix_mm': 2,
                    'wormix_ok': 3}
    line_fields = line.strip().split("/")
    social = line_fields[3]
    print(line_fields[3])
    return social_folders[social]

numbers = 'First', 'Second', 'Third'  # < -
testsortf = open('./testsort.txt')
contents = testsortf.readlines()
contents[-1] = f'{contents[-1]}\n'
contents.sort(key=my_sort)
for i, line in enumerate(contents):
    test_out.write(f'{numbers[i]}:\n{line}')  # No., newline, content
    if i+1 < len(contents):  # Don't add additional \n for last line
        test_out.write('\n')

testsortf.close()
test_out.close()

另一项建议:
在Python中使用with ... as f是一种很好的做法,因为即使出现错误,它也会关闭文件。 最后的代码是:

def my_sort(line):
    social_folders = {'engine': 1,
                    'wormix_mm': 2,
                    'wormix_ok': 3}
    line_fields = line.strip().split("/")
    social = line_fields[3]
    print(line_fields[3])
    return social_folders[social]

numbers = 'First', 'Second', 'Third', 'Fourth'
with open('./testsort.txt') as testsortf, \
     open('./test_out999.txt', "w") as test_out:
    contents = testsortf.readlines()
    contents[-1] = f'{contents[-1]}\n'
    contents.sort(key=my_sort)
    for i, line in enumerate(contents):
        test_out.write(f'{numbers[i]}:\n{line}')
        if i+1 < len(contents):  # Don't add additional \n for last line
            test_out.write('\n')
    # No need to call close()!

注释

  1. 有关enumerate()的更多信息,请参见PEP 279
  2. f字符串(f'...{...}...')是由PEP 498在Python3.6中添加的。对Python3.5或更低版本使用'...{}...'.format(...)

相关问题 更多 >

    热门问题