I'm trying to use a while loop to loop through .xml files in a folder. However, files are being added to the folder whilst the while loop is running. This is a shortened version of the code I currently use:
import os
my_folder = "d:\\xml\\"
while True:
files = [f for f in os.listdir(my_folder) if f.endswith(".xml")]
while files:
for file in files:
# do whatever with the xml file
os.remove(my_folder + file)
files = [f for f in os.listdir(my_folder) if f.endswith(".xml")]
What I would like to do is tidy up the code by only having one line filling the files list. I'd like to have something like:
while files = [f for f in os.listdir(my_folder) if f.endswith(".xml")]:
But, I know this won't work. I would imagine that Python is capable of this, but I don't know the correct syntax.
Added note: I'm using Windows 10 with Python 3.7.6
1 Answer 1
You could simplify your code by removing the inner while loop and the second assignment to files. This will loop indefinitely, see if there are xml files in the directory, and if so process and delete them, before continuing to loop. (You might also add a short sleep in case of no new files.)
while True:
files = [f for f in os.listdir(my_folder) if f.endswith(".xml")]
for file in files:
# do whatever with the xml file
os.remove(my_folder + file)
As shown in the other answer, you could also use the := operator and something like the following...
while True:
while (files := [...]):
...
... but this would behave exactly the same as without the inner while. Only if you e.g. want to do something when there are temporarily no files left, i.e. have code in the outer loop that's not in the inner loop, this may make a difference.
2 Comments
while (files := [...]) or True:. But the first solution still seems better - especially if for path in glob(...): is used instead.while with := would just save one line; you'd still need the for, and you could do the same with moving the list comprehension directly to the for loop head. But using for file in glob.glob("*.xml") is indeed a nice idea that makes it more readable.
whileand use justwhile True: files = ...; for file in files: ...?while files := [f for f...