I'm writing some code that increments the number at the end of a filename until it's no longer overwriting an existing file. I'm creating several files, all with the same base filename but different extensions, none of which I want to overwrite.
Naive version:
prefix = 'hello0'
while os.path.exists(prefix + '.abc') or os.path.exists(prefix + '.def') or os.path.exists(prefix + '.ghi'):
n = int(prefix[-1])
prefix = prefix[:-1] + str(n + 1) # I know this doesn't work when n reaches two digits; my full code involves a regular expression
The condition could obviously get very long and ugly when there are more than a couple of extensions. I abstracted this into a for
loop.
My version:
prefix = 'hello0'
extensions = ('.abc', '.def', '.ghi') # there could be even more than this
condition = True
while condition:
condition = False
# if any of the paths still exist, set the condition back to True
for extension in extensions:
if os.path.exists(prefix + extension):
condition = True
n = int(prefix[-1])
prefix = prefix[:-1] + str(n + 1)
I still feel this to be a little bit clunky: it's not entirely clear what the while
loop is actually testing. Is it possible to build a Boolean expression dynamically, rather than setting a Boolean value?
I think the following might work (I haven't tested it, I only thought of it while writing this!) but I don't think I should have to resort to eval
:
prefix = 'hello0'
extensions = ('.abc', '.def', '.ghi')
test = 'False'
for extension in extensions:
test += " or os.path.exists(prefix + '" + extension + "')"
while eval(test):
n = int(prefix[-1])
prefix = prefix[:-1] + str(n + 1)
You might want to use the any()
built-in with a generator:
while any(os.path.exists(prefix + extension) for extension in extensions):
# then increment prefix and try again, as in your example code
This computes the True
or False
that you need with a simpler syntax.
In general, if I ever feel the temptation to use eval()
in a dynamic language like Python, then it means that there is an important language feature that I need to learn about. Dynamic languages are supposed to make code beautiful without the disaster of trying to write and maintain code-that-writes-more-code — so you have done exactly the right thing here by asking about your approach.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With