11

next()我想使用with循环一层os.walk

我的代码的关键行:

for root, dirs, files in os.walk(dir).next(1): 

错误:

AttributeError:“生成器”对象没有属性“下一个”

我尝试按照社区的建议使用.next(x)替换旧next()[1]的,但这也不起作用。

4

2 回答 2

23

您正在使用 python3。在 python3 中,该next()方法被替换为__next__. 这些方法接受任何参数(即a.__next__(1)错误)。他们将迭代器推进1next重复调用更多元素来推进它。

如果您想将迭代器推进一次,我建议使用next内置函数:

>>> L = (x for x in range(10))
>>> next(L)
0
>>> next(L)
1

注意:next我相信内置函数是在python2.6中添加的,因此即使在python2中也可以安全使用。

但是,在您的代码中,调用根本没有意义next。你想用它来达到什么目的?

正在做:

for root, dirs, files in next(os.walk(dir)):

将引发错误,因为next返回 的第一个元素os.walk,它是一个三元素元组,包含字符串列表。但for循环将遍历元组,试图将单个列表解压缩到root, dirs, files. 如果任何目录的文件/子目录多于或少于 3 个,则代码将失败。

如果您只想跳过第一个目录,则必须next单独调用:

iterable = os.walk(directory)
next(iterable)   # throw away first iteration
for root, dirs, files in iterable:
   #...

如果您只想在目录上进行迭代,正如 Martijn 所推测的那样,那么您不必特别做任何事情。只是不要在循环中使用rootand变量。files在这种情况下,我建议将它们重命名为_,这通常用于指示我们必须分配的变量,但根本不使用:

for _, dirs, _ in os.walk(directory):
    # Work only on "dirs". Don't care for "_"s

如果您想使用n可迭代对象的第一个元素,您可以使用itertools.isliceandcollections.deque来快速完成它并且不消耗内存:

from itertools import islice
from collections import deque

def drop_n_elements(n, iterable):
    deque(islice(iterable, n), maxlen=0)

然后将其用作:

iterable = os.walk(directory)
drop_n_elements(N, iterable) # throw away first N iterations
for root, dirs, files in iterable:
    # ...

我突然想到有一种更快、更简单的方法来删除可迭代的前 n 个元素:

def drop_n_elements(n, iterable):
    next(islice(iterable, n, n), None)

它比 using 稍微快一些,deque(..., maxlen=0)因为它只next调用islice.

于 2013-08-31T12:00:01.243 回答
1
for root, dirs, files in os.walk(dir).__next__()[1]:
于 2018-05-04T06:28:15.923 回答