FOR循环范围一次处理一定数量的文件

时间:2012-11-22 16:33:49

标签: python loops range

我有一个for循环,它运行一个目录并处理那里的文件,但我想一次只处理一定数量的文件。例如,我有一个包含1000个文件的目录,但我每天只能处理250个文件,因此第一次运行脚本时,它会处理前250个,然后是下一个250,依此类推。依此类推。 / p>

首先,我正在检查文件名,该文件记录了已经同步的文件的名称,因此我不会再次处理它们。然后我想处理下面的n个文件,其中我有一个变量synclimit = n

我考虑将in range语句添加到for循环中,如下所示:

tree = ET.parse("sync_list.xml")
root = tree.getroot()
synced = [elt.text for elt in root.findall('synced/sfile')]
for filename in os.listdir(filepath) and in range (0, synclimit) :
    if fnmatch.fnmatch(filename, '*.txt') and filename not in synced:
    filename = os.path.join(filepath, filename)
    result = plistlib.readPlist(filename)

但是,我很确定这只会检查目录中前n个文件的数量。我应该将range语句添加到if语句中吗?像:

tree = ET.parse("sync_list.xml")
root = tree.getroot()
synced = [elt.text for elt in root.findall('synced/sfile')]
for filename in os.listdir(filepath):
    if fnmatch.fnmatch(filename, '*.txt') and filename not in synced and in range (0, synclimit):
    filename = os.path.join(filepath, filename)
    result = plistlib.readPlist(filename)

还是有更简单的方法吗?谢谢。

1 个答案:

答案 0 :(得分:1)

只需保留一个单独的计数器并递增,然后测试它是否已达到synclimit。就那么简单。这里没有必要太聪明了:

processed = 0
for filename in os.listdir(filepath):
    if not filename.endswith('.txt') or filename in synched:
        continue
    # process
    processed += 1
    if processed >= synclimit:
        break  # done for today.

或者,由于os.listdir()会返回一个列表,如果您已经在一个集合中已经同步了文件名列表,则可以对其进行过滤,然后将其切割为最大值:

synced = set(elt.text for elt in root.findall('synced/sfile'))
to_process = [f for f in os.listdir(filepath) if f.endswith('.txt') and f not in synched]

for filename in to_process[:synclimit]:
    # process

请注意,我只测试.endswith('.txt')而不是使用简单的文件匹配器;测试归结为同样的事情。