key
关键字必须是可调用的。输入序列中的每个条目都会调用它。
Alambda
是创建这样一个可调用对象的简单方法:
sorted(..., key=lambda line: stringsplit(line))
不过,我会非常谨慎地对fileinput
许多大文件的输出进行排序。sorted()
必须将所有行读入内存才能对它们进行排序。如果您的文件很多和/或很大,您将用完所有内存,最终导致MemoryError
异常。
首先使用不同的方法对日志进行预排序。您可以使用 UNIX 工具sort
,或者使用外部排序技术。
如果您的输入文件已经排序,您可以使用相同的键合并它们:
import operator
def mergeiter(*iterables, **kwargs):
"""Given a set of sorted iterables, yield the next value in merged order"""
iterables = [iter(it) for it in iterables]
iterables = {i: [next(it), i, it] for i, it in enumerate(iterables)}
if 'key' not in kwargs:
key = operator.itemgetter(0)
else:
key = lambda item, key=kwargs['key']: key(item[0])
while True:
value, i, it = min(iterables.values(), key=key)
yield value
try:
iterables[i][0] = next(it)
except StopIteration:
del iterables[i]
if not iterables:
raise
然后传入你打开的文件对象:
files = [open(f) for f in glob.glob('logs/*')]
for line in mergeiter(*files, key=lambda line: stringsplit(line)):
# lines are looped over in merged order.
但是您需要确保函数返回的stringsplit()
值按照输入日志文件中的顺序返回。