我试图从Apache access日志文件中整理出最小页面加载时间和最大页面加载时间。 在解析日志文件并使用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'”错误为“counter”,因此需要使用元组。 下面的排序方法也是一样的:
print(sorted(abcd(serve_time)))
[['1660'], ['1971'], ['2020'], ['2358'], ['2384'], ['2523'], ['2976'], ['3939'], ['455'], ['677']]
这是按字符串排序,而不是按数字排序
和“3”>; “2”
如果要按数字排序,请将lambda更改为:
key=lambda i: int(i[0])
它们是弦。 由于字符串是序列,所以字符串相等性首先由第一个字符确定。 这里的第一个字符是一个数字。 以数字6作为第一个字符的字符串是该顺序中的最后一个,因此它正确地排序了字符串。
要修复它,只需将值转储到int。
序列对象通常可以与具有相同序列类型的其他对象进行比较。 比较使用词典的顺序:首先比较前两个条目,如果它们不同,这就决定了比较的结果; 如果它们相等,则比较接下来的两项,依此类推,直到其中一个序列耗尽。 如果要比较的两个条目本身是相同类型的序列,则递归地进行词典学比较。 如果两个序列的所有项比较相等,则认为序列相等。 如果一个序列是另一个序列的初始子序列,则较短的序列就是较小(较小)的序列。 字符串的词典排序使用Unicode代码点数对单个字符进行排序。 同类型序列之间比较的一些例子:
https://docs.python.org/3/tutorial/datastructures.html#比较序列和其他类型