【问题标题】:Python sorted not sorting Counter output properlyPython排序未正确排序计数器输出
【发布时间】:2020-07-12 14:55:46
【问题描述】:

我正在尝试从 Apache 访问日志文件中整理出最小页面加载时间和最大页面加载时间。在解析日志文件并使用 sorted 排序后,我看到了奇怪的排序。

#!/usr/bin/python3

from collections import Counter 
import re
import sys

logfile = sys.argv[1]

def abcd(match):
    clean_log = []

    for line in open(logfile):
        try:
            if re.findall(match, line):
                clean_log.append(re.findall(match, line))
        except ValueError:
            pass
    return(clean_log)


serve_time = "\d+$"

print(sorted(Counter(map(tuple, abcd(serve_time))).most_common(), key = lambda i: (i[0])))

上面的代码排序千分之一,然后才排序百:

$ ./log-parser.py access.log
[(('1660',), 1), (('1971',), 1), (('2020',), 1), (('2358',), 1), (('2384',), 1), (('2523',), 1), (('2976',), 1), (('3939',), 1), (('455',), 1), (('677',), 1)]

如您所见,455 和 677 位于末尾,但如果您分别查看千分之几和百分之几,则排序正确。

有人可以解释一下吗?

顺便说一句,如果我不使用映射到元组,我会收到“计数器”的“TypeError:unhashable type:'list'”错误,因此需要使用元组。使用下面的方法排序是同样的故事:

    print(sorted(abcd(serve_time)))

[['1660'], ['1971'], ['2020'], ['2358'], ['2384'], ['2523'], ['2976'], ['3939'], ['455'], ['677']]

【问题讨论】:

    标签: python sorting tuples counter


    【解决方案1】:

    它们是字符串。字符串相等首先由第一个字符确定,因为字符串是序列。第一个字符在这里是一个数字。以数字 6 作为第一个字符的字符串是该顺序中的最后一个字符,因此它可以正确地对字符串进行排序。

    要修复它,您只需将值转储到 int。

    序列对象通常可以与具有相同序列类型的其他对象进行比较。比较使用字典顺序:首先比较前两项,如果它们不同,则确定比较的结果;如果它们相等,则比较接下来的两项,依此类推,直到任一序列用完。如果要比较的两个项目本身是相同类型的序列,则以递归方式进行字典比较。如果两个序列的所有项比较相等,则认为这两个序列相等。如果一个序列是另一个序列的初始子序列,则较短的序列是较小(较少)的序列。字符串的字典顺序使用 Unicode 代码点编号对单个字符进行排序。一些相同类型序列之间的比较示例:

    https://docs.python.org/3/tutorial/datastructures.html#comparing-sequences-and-other-types

    【讨论】:

      【解决方案2】:

      它是按字符串而不是按数字排序

      和'3' > '2'

      如果您想按数字排序,请将您的 lambda 更改为:

      key=lambda i: int(i[0])
      

      【讨论】:

      • 很高兴能为您提供帮助,如果解决了您的问题,请将其标记为“已回答”。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多