我怎样才能通过I';在Python中,我在for循环中迭代到sort/sorted函数?
我正在尝试循环许多日志文件,需要对循环的所有文件中的文件条目(行)进行排序 这就是我正在做的:我怎样才能通过I';在Python中,我在for循环中迭代到sort/sorted函数?,python,sorting,for-loop,parameters,key,Python,Sorting,For Loop,Parameters,Key,我正在尝试循环许多日志文件,需要对循环的所有文件中的文件条目(行)进行排序 这就是我正在做的: import glob f = glob.glob('logs/') for line in sorted(fileinput.input(f), key=stringsplit(line)): print line 因此,我打开所有文件,然后想使用stringsplit函数(从文件条目中提取日期)作为排序标准 问题是,这样做会给我一个错误,说: name 'line' is not defi
import glob
f = glob.glob('logs/')
for line in sorted(fileinput.input(f), key=stringsplit(line)):
print line
因此,我打开所有文件,然后想使用stringsplit函数(从文件条目中提取日期)作为排序标准
问题是,这样做会给我一个错误,说:
name 'line' is not defined
问题:是否无法将作为参数循环的
行
传递到排序函数中?如何做到这一点
谢谢 关键字
必须是可调用的。输入序列中的每个条目都会调用它
lambda
是创建此类可调用函数的简单方法:
sorted(..., key=lambda line: stringsplit(line))
不过,我会非常小心地将fileinput
的输出与许多大文件进行排序sorted()
必须将所有行读入内存才能对它们进行排序。如果文件很多和/或很大,则会耗尽所有内存,最终导致MemoryError
异常
首先使用不同的方法对日志进行预排序。您可以使用UNIX工具排序
,也可以使用
如果输入文件已排序,则可以使用相同的键合并它们:
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()
函数返回输入日志文件中按顺序排列的值。关键字必须是可调用的。输入序列中的每个条目都会调用它
lambda
是创建此类可调用函数的简单方法:
sorted(..., key=lambda line: stringsplit(line))
不过,我会非常小心地将fileinput
的输出与许多大文件进行排序sorted()
必须将所有行读入内存才能对它们进行排序。如果文件很多和/或很大,则会耗尽所有内存,最终导致MemoryError
异常
首先使用不同的方法对日志进行预排序。您可以使用UNIX工具排序
,也可以使用
如果输入文件已排序,则可以使用相同的键合并它们:
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()
函数返回的值与输入日志文件中的顺序相同。请尝试key=lambda line:stringsplit(line)
排序在开始在for循环中迭代之前完成。尝试key=lambda-line:stringsplit(line)
排序在开始在for循环中迭代之前完成。尝试key=lambda-line:stringsplit(line)
。排序是在开始在for-loop.ah中迭代之前完成的。谢谢Python的第一周。。。你想回答这个问题吗?试试key=lambda-line:stringsplit(line)
。排序是在开始在for-loop.ah中迭代之前完成的。谢谢Python的第一周。。。你不想回答这个问题吗?很好的提示。我要检查我的记忆能吞下多少行…:-)嗯。我需要按日期和时间排序。单独的文件按日期时间排序,但我只能对所有文件进行全局排序,以获得项目a-Z,因此合并已排序的文件不会有帮助,是吗?@frequent:如果单独的文件已按日期排序,则可以合并它们。请参阅我链接的问题,您可以采用此处显示的技术来合并文件。@frequent:使用我的mergeiter()
函数更新了我的答案。@frequent:抱歉,注意到mergeiter()
示例调用中缺少*
。也纠正了这一点。多任务处理,所以不要混得那么好…:-)好提示。我要检查我的记忆能吞下多少行…:-)嗯。我需要按日期和时间排序。单独的文件按日期时间排序,但我只能对所有文件进行全局排序,以获得项目a-Z,因此合并已排序的文件不会有帮助,是吗?@frequent:如果单独的文件已按日期排序,则可以合并它们。请参阅我链接的问题,您可以采用此处显示的技术来合并文件。@frequent:使用我的mergeiter()
函数更新了我的答案。@frequent:抱歉,注意到mergeiter()
示例调用中缺少*
。也纠正了这一点。多任务处理,所以不要混得那么好…:-)