【问题标题】:How to sort numerically by what's between square brackets如何按方括号之间的内容进行数字排序
【发布时间】:2018-10-02 13:48:18
【问题描述】:

我有以下场景,其中一个文本文件具有以下输出:

DecodingIndex[ 1]   PresentationIndex[ 2]
DecodingIndex[ 2]   PresentationIndex[ 3]
DecodingIndex[ 3]   PresentationIndex[ 1]
etc...

由于它显示 DecodingIndex 中的数字顺序,我希望它按 PresentationIndex 排序。像下面这样:

DecodingIndex[ 3]   PresentationIndex[ 1]
DecodingIndex[ 1]   PresentationIndex[ 2]
DecodingIndex[ 2]   PresentationIndex[ 3]

有没有一种简单的方法可以在 Python 中做到这一点?这些数字一直达到数万。方括号之间的距离对于小于 10 的数字总是有间隙,然后拥抱数字例如 DecodingIndex[32100]

希望这是有道理的,感谢您的帮助!

=======

这是我尝试过的: 1)我遍历文件中的每一行并存储到一个行[]列表中 2) 遍历lines[] 列表中的每个项目,同时使用以下正则表达式模式re.compile(r'PresentationIndex\[(.*?)\]') 3)然后我使用 group() 从结果中获取匹配项并将这些值存储在一个新列表中 4)然后我通过首先将项目转换为int,然后排序,然后将其转换回这样的字符串来对列表进行数字排序 5)现在我遍历该列表并在其中插入单词 PresentationIndex 和方括号 6)使用现在排序的 PresentationIndex 列表,我遍历其中的每一个。对于每次迭代,我都会遍历整个输出文本文件以搜索相关行并将其附加到最终列表中。这样我就可以按照我想要的顺序获得输出。

我从一个大约 32,000 行的文件开始。完成这种排序大约需要 3 个小时...

【问题讨论】:

  • 有一个简单的方法。 尝试了什么?
  • 我已经把这个问题抽象了很多。不确定如何粘贴所有代码..?但是我使用正则表达式来匹配 PresentationIndex 括号之间的所有内容,然后将它们按数字排序到一个列表中。然后使用它,遍历相应行的原始输出文件......简而言之
  • 那么问题出在哪里?
  • 不要粘贴所有代码,粘贴最少量的相关代码来说明问题。
  • 执行我的脚本需要 3 个小时。这似乎效率太低,我想知道还有什么其他方法,因为我的方法肯定不是最好的:)

标签: python sorting brackets


【解决方案1】:

您可以在文件上调用sorted()(因为打开的文本文件在迭代时就像一个行列表)使用一个函数,该函数采用一行并将括号之间的内容提取为key=参数

import re

def extract_presentation_index(line):
    return int(re.search("\[\s*(\d+)\s*\]$", line).group(1))
    # alternatively, you don't have to use regex
    #return int(line.split('[')[2].split(']', 1)[0].strip())

with open('/path/to/your/file') as f:
    sorted_lines = sorted(f, key=extract_presentation_index)
    print(''.join(sorted_lines), end='')

end='' 只是为了避免在末尾添加额外的换行符 (\n)。

【讨论】:

    【解决方案2】:

    这可能不是最理想的,但应该可以解决问题:

    import re
    from collections import OrderedDict
    
    my_string = '''DecodingIndex[ 1]   PresentationIndex[ 2]
    DecodingIndex[ 2]   PresentationIndex[ 3]
    DecodingIndex[ 3]   PresentationIndex[ 1]'''
    
    my_list = list(my_string.split("\n"))
    
    my_dict = {}
    
    for x in my_list:
        match = re.search("\[\s*(\d+)\s*\]$", x)
        my_dict[match.group(1)] = x
    
    ordered_dict = OrderedDict(sorted(my_dict.items(), key=lambda t: t[0]))
    print(ordered_dict)
    

    对您来说可能很慢的部分是读取文件?这一切都应该运行得非常快。我从一个字符串开始,假设您可以将文件转换为字符串。我在\n 上拆分了字符串,但您也可以只读取文件,因此每一行都是列表中的一个项目。

    然后我循环它并用正则表达式匹配你想要排序的那个数字。在dict 中将该值设为key。然后使用collections 按键对字典进行排序。全部完成!希望对您有所帮助。

    【讨论】:

    • 谢谢狙击手。是的,我还在将我认为导致速度变慢的输出写入文件!
    • @Baba.S 啊,好的。写出文件的专业提示。试着用“块”写出来。附加到一个像 1000 行这样的字符串,然后把它们写出来。重置字符串,追加 1000 行等。玩弄那个数字,10000 行,50000 行等。会有一个甜蜜点。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-12-24
    • 2022-01-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-18
    相关资源
    最近更新 更多