首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Python上按关键字对txt行进行排序

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

Stack Overflow用户
提问于 2021-04-24 04:07:31
回答 2查看 93关注 0票数 0

我在python上遇到了问题:我想在下面的期望输出中对.txt进行排序,但不是这个输出,而是用连接的第一行和第二行以及文件末尾的空行进行错误输出,为什么会发生这种情况呢?

提前感谢您的帮助

输入文件:

代码语言:javascript
复制
https://markus.rmart.ru/wormix_mm/preloader/
https://markus.rmart.ru/wormix_ok/preloader/
https://markus.rmart.ru/engine/preloader/

期望产出:

代码语言:javascript
复制
https://markus.rmart.ru/engine/preloader/
https://markus.rmart.ru/wormix_mm/preloader/
https://markus.rmart.ru/wormix_ok/preloader/

实际产出:

代码语言:javascript
复制
https://markus.rmart.ru/engine/preloader/https://markus.rmart.ru/wormix_mm/preloader/
https://markus.rmart.ru/wormix_ok/preloader/

代码:

代码语言:javascript
复制
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()

但是,当我用line.rstrip('\n')删除最后一个"\n“并手动添加"\n”时,我接受这个输出(文件末尾有多余的空行):

代码语言:javascript
复制
https://markus.rmart.ru/engine/preloader/
https://markus.rmart.ru/wormix_mm/preloader/
https://markus.rmart.ru/wormix_ok/preloader/

小修理:

代码语言:javascript
复制
test_out.write(line.rstrip('\n') + "\n")

那么,为什么会发生这种情况,以及我如何获得理想的输出?

如果有人能帮我解决问题下一步..。如何获得这个输出?

代码语言:javascript
复制
First:
https://markus.rmart.ru/engine/preloader/

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

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

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-04-24 04:43:26

你的意外:

代码语言:javascript
复制
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/

因此,content的2个元素有\n后缀,而1没有后缀,从而导致了不同的行为。

简单的修复方法不是每次添加额外的换行符,而是只添加最后一行:

代码语言:javascript
复制
contents = testsortf.readlines()
contents[-1] = f'{contents[-1]}\n'

如果contents可能是空的:

代码语言:javascript
复制
contents = testsortf.readlines()
if contents:
    contents[-1] = f'{contents[-1]}\n'

所以我们现在有了代码:

代码语言:javascript
复制
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

代码语言:javascript
复制
numbers = 'First', 'Second', 'Third'

然后使用方便的enumerate()

代码语言:javascript
复制
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是一个很好的实践,因为即使出现错误,它也会关闭文件。所以最后的代码:

代码语言:javascript
复制
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. 有关佩普279的更多信息,请参见enumerate()
  2. F-字符串(f'...{...}...')是由佩普498在Python3.6中添加的。对Python3.5或更低版本使用'...{}...'.format(...)
票数 0
EN

Stack Overflow用户

发布于 2021-04-24 04:20:33

当您将\n添加到每一行时,\n也会添加到最后一行。在除换行符之外的每一行上,都会在之前创建的换行符上写一些东西--但是,在最后一行,换行符中没有写任何东西,只留下空白。下面是一个示例:

迭代1:

代码语言:javascript
复制
https://markus.rmart.ru/wormix_mm/preloader/

迭代2:

代码语言:javascript
复制
https://markus.rmart.ru/wormix_mm/preloader/
https://markus.rmart.ru/wormix_ok/preloader/

注意我们在Interation 1中创建的换行符现在是如何包含文本的。如果没有换行符,则如下所示:

代码语言:javascript
复制
https://markus.rmart.ru/wormix_mm/preloader/https://markus.rmart.ru/wormix_ok/preloader/

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

最后,迭代3:

代码语言:javascript
复制
https://markus.rmart.ru/engine/preloader/
https://markus.rmart.ru/wormix_mm/preloader/
https://markus.rmart.ru/wormix_ok/preloader/

正如您所看到的,迭代3之后没有写任何东西,留下最后一行空白。

为了解决这个问题,您必须做一个简单的检查,看看该行当前是否是最后一行(用下面的代码替换for line in contents for循环):

代码语言:javascript
复制
for i in range(len(contents)):
    test_out.write(line.rstrip('\n'))
    if i < len(contents) - 1:
        test_out.write("\n")

为了做您想做的事情( FirstSecondThird),您只需列出一个满是这些单词的列表:

代码语言:javascript
复制
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

(我还没有测试过这个,请告诉我如果它不起作用)

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67239239

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档