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?

Author: Martijn Pieters, 2012-08-23

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']
 51
Author: Martijn Pieters,
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.

 7
Author: hochl,
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')))
 0
Author: apparat,
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.

 0
Author: grieve,
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
 -1
Author: Burhan Khalid,
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