Lectura de archivos en un orden particular en python
Digamos que tengo tres archivos en una carpeta: file9.txt, file10.txt y file11.txt y yo queremos leerlos en este orden particular. ¿Alguien puede ayudarme con esto?
Ahora mismo estoy usando el código
import glob, os
for infile in glob.glob(os.path.join( '*.txt')):
print "Current File Being Processed is: " + infile
Y lee el primer file10.txt y luego file11.txt y luego file9.txt.
¿Puede alguien ayudarme a obtener el pedido correcto?
5 answers
Los ficheros del sistema de ficheros no están ordenados. Puede ordenar los nombres de archivo resultantes usted mismo utilizando el sorted()
función :
for infile in sorted(glob.glob('*.txt')):
print "Current File Being Processed is: " + infile
Tenga en cuenta que la llamada os.path.join
en su código es una no-op; con un solo argumento no hace nada más que devolver ese argumento inalterado.
Tenga en cuenta que sus archivos se ordenarán en orden alfabético, lo que pone 10
antes de 9
. Puede utilizar una función de tecla personalizada para mejorar la ordenación:
import re
numbers = re.compile(r'(\d+)')
def numericalSort(value):
parts = numbers.split(value)
parts[1::2] = map(int, parts[1::2])
return parts
for infile in sorted(glob.glob('*.txt'), key=numericalSort):
print "Current File Being Processed is: " + infile
La función numericalSort
divide cualquier dígito en un nombre de archivo, lo convierte en un número real, y devuelve el resultado para ordenar:
>>> files = ['file9.txt', 'file10.txt', 'file11.txt', '32foo9.txt', '32foo10.txt']
>>> sorted(files)
['32foo10.txt', '32foo9.txt', 'file10.txt', 'file11.txt', 'file9.txt']
>>> sorted(files, key=numericalSort)
['32foo9.txt', '32foo10.txt', 'file9.txt', 'file10.txt', 'file11.txt']
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-08-23 14:55:10
Puede envolver su expresión glob.glob( ... )
dentro de una instrucción sorted( ... )
y ordenar la lista de archivos resultante. Ejemplo:
for infile in sorted(glob.glob('*.txt')):
Puede dar sorted
una función de comparación o, mejor, usar el argumento key= ...
para darle una clave personalizada que se usa para ordenar.
Ejemplo:
Hay los siguientes archivos:
x/blub01.txt
x/blub02.txt
x/blub10.txt
x/blub03.txt
y/blub05.txt
El siguiente código producirá la siguiente salida:
for filename in sorted(glob.glob('[xy]/*.txt')):
print filename
# x/blub01.txt
# x/blub02.txt
# x/blub03.txt
# x/blub10.txt
# y/blub05.txt
Ahora con la función clave:
def key_func(x):
return os.path.split(x)[-1]
for filename in sorted(glob.glob('[xy]/*.txt'), key=key_func):
print filename
# x/blub01.txt
# x/blub02.txt
# x/blub03.txt
# y/blub05.txt
# x/blub10.txt
EDITAR: Posiblemente esta clave la función puede ordenar sus archivos:
pat=re.compile("(\d+)\D*$")
...
def key_func(x):
mat=pat.search(os.path.split(x)[-1]) # match last group of digits
if mat is None:
return x
return "{:>10}".format(mat.group(1)) # right align to 10 digits.
Seguro que se puede mejorar, pero creo que entiendes el punto. Las rutas sin números se dejarán solas, las rutas con números se convertirán en una cadena que tenga 10 dígitos de ancho y contenga el número.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-08-23 14:58:08
glob.glob(os.path.join( '*.txt'))
Devuelve una lista de cadenas, por lo que puede ordenar fácilmente la lista usando la función pythons sorted () .
sorted(glob.glob(os.path.join( '*.txt')))
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-08-23 14:40:44
Necesita cambiar el orden de 'asciibético' a numérico aislando el número en el nombre del archivo. Puedes hacerlo así:
import re
def keyFunc(afilename):
nondigits = re.compile("\D")
return int(nondigits.sub("", afilename))
filenames = ["file10.txt", "file11.txt", "file9.txt"]
for x in sorted(filenames, key=keyFunc):
print xcode here
Donde puede establecer nombres de archivo con el resultado de glob.glob ("*.txt");
Additinally la función keyFunc asume que el nombre del archivo tendrá un número en él, y que el número está solo en el nombre del archivo. Puede cambiar esa función para que sea tan compleja como necesite para aislar el número que necesita ordenar.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-08-23 14:50:28
for fname in ['file9.txt','file10.txt','file11.txt']:
with open(fname) as f: # default open mode is for reading
for line in f:
# do something with line
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-08-23 14:31:47