Delete list item if directory does not exist

2

I have a list containing the path of some directories, I want to check if each directory exists, for that I use os.path.exists() , if a directory does not exist, I use the remove() method to remove it from the list, looping for it ignores the next item in the list, for example, if a:/ does not exist it pays it but skips b:/ and erases c:/ and so on.

Here is the code I'm using:

def conf_dir_exist_b(lines):
    for lna in lines:
        for lnb in lna:
            if(os.path.exists(lnb) == False):
                lna.remove(lnb)
            else:
                pass
    return lines

if __name__ == '__main__':
conf_dir_exist_b(['a:/', 'b:/', 'w:/', 'g:/', 'f:/', 'd:/Downloads/Torrent/End', 'x:/files.2t', 'y:/files.1t'], ['d:/Dropbox/project/rato_bat', 'x:/bb'])
    
asked by anonymous 26.07.2016 / 16:11

1 answer

3

According to documentation this is because:

  

(In free translation)

     

There is a subtlety when the sequence is being modified by the loop   (this can only occur through mutable sequences, ie lists ). a   internal counter is used to keep track of which item is used   and it is incremented at each iteration. When this counter   has reached the length of the sequence the loop ends.

     

This means that if the set excludes the current item (or a previous one)   of the sequence, the next item is ignored (once you get the   index of the current item that has already been treated ).

     

Similarly, if the set inserts an item in the sequence before the item   current item, the current item will be dealt with again next time through the    loop . This can lead to bugs that can be avoided by making a copy   temporary using a slice of the entire sequence, [...]

One way for you to do this is to scroll through the entire list and check if the current item is an existing directory, if it is, you enter it into a new list, at the end of the iteration you return that list, see an example :

def checkDirExist(lista):
    # Variável que vai armazenar os diretórios existentes
    resultado = []

    # Percorre cada uma das listas
    for diretorios in lista:
        # Percorre os itens das listas
        for diretorio in diretorios:
            # Verifica se o item atual é um diretório existente
            if os.path.exists(diretorio):
                # Se for, armazena o item na nova lista
                resultado.append(diretorio)
            # Caso não exista o diretório   
            #else:
            #   print("O diretório {0} não existe!".format(diretorio))

    return resultado

# Lista de listas
diretorios = [
               ['a:/', 'b:/', 'w:/', 'g:/', 'f:/',
                'd:/Downloads/Torrent/End', 'x:/files.2t', 'y:/files.1t'], 
               ['d:/Dropbox/project/rato_bat', 'x:/bb'],
             ]

diretoriosExistentes = checkDirExist(diretorios)

# ... continuação do teu código ...

Another way is to use List Comprehensions , which consists of creating a new list with the items you want:

diretorios[:] = [listas for listas in diretorios for dir in listas if os.path.exists(dir)]
print (diretorios)
    
26.07.2016 / 18:07