在迭代完成之前退出循环的Python解释器:

2024-10-02 22:36:16 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在构建一个Python脚本,从任意一组子目录中选择并打开文件。为此,我正在构建一个带有for循环的函数,以生成一个目录中所有文件的列表,以及该目录中所有子目录的另一个列表。然后另一个for循环通过递归调用同一个函数来更改每个子目录。我已经在调试模式下反复使用了这个函数,并且非常仔细地观察了每个变量一步一步地变化。你知道吗

我完全困惑,因为每个循环都会运行一段时间,但之后它就没有结束就退出了。通常在编程中,事情要么完全起作用,要么根本不起作用,但很少只起到一半的作用。两个循环都会这样做,当对函数的第二个调用退出时,它不会返回到第一个调用以完成第二个循环,而是完全退出对函数的所有调用。这是代码,非常感谢您的帮助:

def descend(directory, depth, dive=-1): # dive=-1 before we have touched the surface 
    global choices                      # list of files to be chosen from later  
    os.chdir(directory)                 # change to target directory 
    dirlist = []                        # empty the list of directories within the directory   
    baseList = os.listdir(directory)    # list of all files and directories

    if dive < depth:                    # depth corresponds to the levels of sub-directories to be searched
        dive += 1                       # effectively starts at 0

        fileIndex=0                     # index as we step through the baseList
        for x in baseList:              # why doesn't this loop complete?
            if os.path.isfile(x) == True:   # if it's a regular file
                path = directory + '/' + baseList.pop(fileIndex)    # create its full path
                choices.append(path)                                # and add that to our list of choices
            elif os.path.isdir(x) == True:                  # if it's a directory
                dirlist.append(baseList.pop(fileIndex))     # add to list of directories to recursively search
            fileIndex += 1      # add 1 to the file index

        for x in dirlist:       # for each item in the list of directories
            nextdir = directory + '/' + dirlist.pop()   # make a variable of its full path
            descend(nextdir, depth, dive)               # pass that back to this function and repeat

我甚至尝试过一些愚蠢的解决方案,比如在循环的底部添加if len(baseList) != 0: continue,这些循环不需要告诉两次,但这对它们都没有帮助。我完全被难住了。你知道吗


Tags: ofthetopath函数forifos
1条回答
网友
1楼 · 发布于 2024-10-02 22:36:16

好吧,我在这里回答我自己的问题,因为我很好奇,做了更多的研究,这是太长的评论。也许这能帮别人弄清楚。在搞清了和IDLE玩的过程后,我在Pydoc中发现了这个:

注意:当序列被 循环(这只能发生在可变序列中,例如列表)。安 内部计数器用于跟踪下一个使用的项目, 每次迭代都是递增的。当这个柜台 达到循环终止的序列长度。这意味着 如果套件从 序列中,将跳过下一项(因为它获取 已处理的当前项)。同样,如果 suite在当前项之前按顺序插入一个项 下一次循环将再次处理当前项。 这可能会导致讨厌的错误,可以通过 使用整个序列的切片进行临时复制,例如

 for x in a[:]:
     if x < 0: a.remove(x)

空闲实验的输入和输出:

>>> baselist=[0,1,2,3,4,5,6,7,8,9]
>>> listeven=[]
>>> listodd=[]
>>> index=0
>>> for x in baselist:
        print('baselist is ', baselist)
        print('listeven is ', listeven)
        print('listodd is ', listodd)
        print('x is ', x)
        print('index is ', index)
        if x % 2 == 0:
            print('appending ', x, ' to listeven by popping from baselist')
            listeven.append(baselist.pop(index))
        else:
            print('appending ', x, ' to listodd by popping from baselist')
            listodd.append(baselist.pop(index))
        index += 1

baselist is  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
listeven is  []
listodd is  []
x is  0
index is  0
appending  0  to listeven by popping from baselist
baselist is  [1, 2, 3, 4, 5, 6, 7, 8, 9]
listeven is  [0]
listodd is  []
x is  2
index is  1
appending  2  to listeven by popping from baselist
baselist is  [1, 3, 4, 5, 6, 7, 8, 9]
listeven is  [0, 2]
listodd is  []
x is  4
index is  2
appending  4  to listeven by popping from baselist
baselist is  [1, 3, 5, 6, 7, 8, 9]
listeven is  [0, 2, 4]
listodd is  []
x is  6
index is  3
appending  6  to listeven by popping from baselist
baselist is  [1, 3, 5, 7, 8, 9]
listeven is  [0, 2, 4, 6]
listodd is  []
x is  8
index is  4
appending  8  to listeven by popping from baselist
>>> baselist
[1, 3, 5, 7, 9]

在中循环中从列表中删除项会导致解释器认为它已经提前完成了迭代,因为它隐藏的内部索引告诉它下一个索引超出范围,这意味着某些值被跳过!你知道吗

现在这个函数看起来像:

def descend(directory, depth, dive=-1): 
global files
os.chdir(directory)
subBranches = []
baseList = os.listdir(directory)
if dive < depth:
    dive += 1
    for x in baseList:
        if os.path.isfile(x) == True:
            path = directory + '/' + x
            files.append(path)
        elif os.path.isdir(x) == True:
            subBranches.append(x)
    for x in subBranches:
        nextdir = directory + '/' + x
        descend(nextdir, depth, dive)

相关问题 更多 >