views:

81

answers:

5
+1  Q: 

Dynamic filenames

So I'm working on a program where I store data into multiple .txt files. The naming convention I want to use is file"xx" where the Xs are numbers, so file00, file01, ... all the way up to file20, and I want the variables assigned to them to be fxx (f00, f01, ...).

How would I access these files in Python using a for loop (or anther method), so I don't have to type out open("fileXX") 21 times?

+1  A: 

Look into python's glob module.

It uses the usual shell wildcard syntax, so ?? would match any two characters, while * would match anything. You could use either f??.txt or f*.txt, but the former is a more strict match, and wouldn't match something like fact_or_fiction.txt while the latter would.

E.g.:

import glob
for filename in glob.iglob('f??.txt'):
    infile = file(filename)
    # Do stuff...
Joe Kington
`glob` is a great option. If, however, you only wanted to access a certain set (say, f0-99 existed, but you only wanted f0-19), then you could use string interpolation: `"f%02d" % 4` becomes `"f04"`.
Amber
+1 to Amber. I would use glob only if I wanted all files matching a pattern. For a series of files whose names are known a priori, I would generate the names.
Noufal Ibrahim
If you need a reference for interpolation: http://docs.python.org/library/stdtypes.html#string-formatting-operations
Amber
@Amber - True, and it's worth noting that glob won't necessarily return things in sorted order (it depends on the underlying filesystem).
Joe Kington
But `sorted()` can be used to fix the latter.
Amber
in addition, glob will only return you **existing** matching files, which does not help you if you want to **create** them as the original poster does (and they did not exist before)
Andre Holzner
+4  A: 

The names are regular. You can create the list of filenames with a simple list comprehension.

["f%02d"%x for x in range(1,21)]
Noufal Ibrahim
For more details on string interpolation: http://docs.python.org/library/stdtypes.html#string-formatting-operations
Amber
A: 

An example of writing t to all files:

for x in range(22): #Remember that the range function returns integers up to 22-1
    exec "f%02d = open('file%02d.txt', 'w')" % (x, x)

I use the exec statement but there's probably a better way. I hope you get the idea though.

NOTE: This method will give you the variable names fXX to work with later if needed. The last two lines are just examples. Not really needed if all you need is to assign fileXX.txt to fXX.

EDIT: Removed the other last two lines because it seemed that people just weren't too happy with me putting them there. Explanations for downvotes are always nice.

vlad003
Why would you use `exec`? You can just reuse the variable storing the file handle, so there's no need to make ones with different names - the only interpolation you need to do is in the filename: `f = open('file%02d.txt' % x, 'w')`.
Amber
Because the OP might need those variables in that format later as he says: *"i want the variables assigned to them to be fxx (f00,f01...)"*. Using just `f =` won't allow him to have those variable names. `exec` allows him to have the variable names he needs
vlad003
You are simultaneously right and wrong =p.
katrielalex
Well I said there's probably a better way than to use `exec` but this method does allow him to have what he wants, no?
vlad003
Well, yes, you're right in that it works but wrong in that `exec` is not the right tool here. I didn't downvote you, by the way.
katrielalex
No worries, I could tell you didn't :P.
vlad003
yah, it works thanks guys. i know that some might think it's bad style, but i just need to get this done :P
pjehyun
+1  A: 

I think the point is the OP wants to register the variables programagically:

for i in range( 20 ):
    locals()[ "f%02d" % i ] = open( "file%02d.txt" % i )

and then e.g.

print( f01 )
...
katrielalex
How would `locals()` be different from `globals()` and `vars()`? If it's all in a loop (and not in a function) you could use either one of them, or am I missing something?
vlad003
@vlad003 - http://docs.python.org/tutorial/classes.html#python-scopes-and-namespaces Also, looking up a global variable is slower than looking up a local variable, so beyond the usual avoidance of global variables, there's a speed difference, as well.
Joe Kington
@vlad003: I never said it was better than `globals()` (it is equivalent to `vars()` with no arguments), I said that it was better than `exec`. However, Joe is right in that it *is* better.
katrielalex
Anything's probably better than `exec`; I only put it here b/c it *works, even though not the best*.@Joe: thanks for the link. I never read the tutorial. I usually learn by doing so I learn as I go.
vlad003
This'd work but I don't like the idea of magically creating variables in my namespace. I'd much prefer that these names were put into a dictionary or something similar.
Noufal Ibrahim
A: 
files = [open("file%02d", "w") for x in xrange(0, 20+1)]
# now use files[0] to files[20], or loop

# example: write number to each file
for n, f in enumerate(files):
  files.write("%d\n" % n)

# reopen for next example
files = [open("file%02d", "r") for x in xrange(0, 20+1)]
# example: print first line of each file
for n, f in enumerate(files):
  print "%d: %s" % (n, f.readline())
Roger Pate