Delete list item if directory does not exist

Asked

Viewed 94 times

2

I have a list containing the path of some directories, I want to check if each directory exists, for this I use the os.path.exists(), if a directory does not exist, I use the method remove() to remove it from the list, but in looping for it ignores the next item on the list, for example, if the a:/ There’s no such thing as pay b:/ and erases the c:/ and so on.

Follow 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'])
  • I don’t understand what the doubt is

  • ok, because it happens when I delete an idem from the list for example: lista = [['a:/', 'b:/', 'c:/'], ['d:/', 'e:/']] I will remove the element 'a:/' within a looping for intoa use the lista.remove('a:/') in the next cycle of for he ignores the b:/ and removes the c:/. understands?

  • Oh yes, I didn’t read it right, thank you

  • @Born That code I posted worked?

  • Do not compare equality with the "True" or "False" valves - the if alone already tests these values. The most "beautiful" form is: if not os.path.exists(lnb) == False: (in fact, Python does not need parentheses in the if expression)

  • @zekk so I didn’t even have time to see it right but it solved however I found that the script became too extensive for little thing.

  • @Born 7 lines, not so much so, also has that other mode, see the last code down there. :)

  • 1

    @zekk I do not say in relation to his way he and practice fast and elegant, but my code in general got extensive I intend to re-evaluate some functionality of the script to let it more lean.

Show 3 more comments

1 answer

3


According to the documentation this happens because:

(In free translation)

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

This means that if the set excludes the current item (or a previous one) of the sequence, the next item will be 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 will be treated 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 to do this is to scroll through the entire list and check if the current item is an existing directory, if it is, you insert it into a new list, at the end of the iteration you return as a result of 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)

Browser other questions tagged

You are not signed in. Login or sign up in order to post.