¡Hola! Si quieres aprender cómo estas funciones actúan detrás de escenas y cómo puedes usar todo su poder, este artículo es para ti.

Comenzaremos viendo conceptos esenciales para trabajar con las funciones listdir y system:

  • El módulo built-in (incorporado) os y cómo importarlo.
  • Los conceptos de "directorio" y "directorio de trabajo actual" (current working directory en inglés).
  • Cómo verificar y cambiar tu directorio de trabajo actual.
  • La diferencia entre un camino absoluto y un camino relativo.

Luego, veremos más detalles sobre las funciones:

  • Cómo trabajar con la función listdir y cuándo usarla.
  • Cómo trabajar con la función system("ls") y cuándo usarla.
  • Ejemplos de ambas y de cómo funcionan detrás de escenas.

Comencemos. ⭐

🔹 El módulo os

Las dos funciones que veremos en tan solo un momento (listdir() y system()), pertenecen al módulo os. Este módulo incluye funciones que puedes usar para interactuar con tu sistema operativo y realizar operaciones como:

  • Crear un directorio.
  • Cambiar el nombre de un directorio.
  • Eliminar un directorio.
  • Mostrar el camino a tu directorio de trabajo actual.
  • ¡Y mucho más!

💡 Datos:

  • Un directorio es lo que comúnmente conocemos como una "carpeta", donde normalmente almacenamos archivos relacionados y/u otros directorios, creando una jerarquía de directorios dentro de directorios llamados subdirectorios. Un ejemplo de un directorio es tu carpeta de "Mis Documentos."
  • Un módulo de Python es un archivo que contiene código de Python relacionado.

Cómo importar el módulo OS

Para usar el módulo os en tu programa, debes importarlo. Importar un módulo te permite tener acceso a todas las funciones y variables definidas en el módulo importado. Importamos un módulo cuando queremos usar su código en nuestro programa.

Para importar el módulo os, solo debes incluir esta línea al inicio de tu programa de Python (en la primer línea) o ejecutarla en el Shell interactivo:

import os

Esto te dará acceso a todas las funciones definidas en el módulo os.

💡 Dato: este módulo ya fue instalado automáticamente cuando instalaste Python 3, así que podrás usarlo inmediatamente.

Para usar las funciones del módulo os, debes añadir os. antes del nombre de la función que se va a llamar, de esta forma:

os.<función>(<parámetros>)

Por ejemplo:

os.mkdir("Carpeta nueva")

Cómo importar funciones específicas

Si solo vas a trabajar con una o dos funciones de este módulo, puedes importarlas individualmente con esta sintaxis:

from <módulo> import <función1>, <función2>, ...

Por ejemplo:

from os import listdir, system

En este caso, puedes llamar a las funciones en tu programa como lo harías normalmente, sin añadir el prefijo os., de esta forma:

<función>(<parámetros>)

Por ejemplo:

mkdir("Carpeta nueva")

🔸 Directorio de trabajo actual

Ahora veremos un concepto muy importante que debes saber antes de comenzar a trabajar con las funciones listdir y system. Tu directorio de trabajo actual, como lo implica su nombre, es el directorio (carpeta) en el cual estás trabajando actualmente.

Puedes verificar tu directorio de trabajo actual con esta función del módulo os:

os.getcwd()

Esto te mostrará el camino a tu directorio de trabajo actual.

💡 Dato: cwd significa "current working directory" (directorio de trabajo actual).

En el Shell Interactivo

Si ejecutamos este comando en el Shell Interactivo de Python (en Windows), veremos lo siguiente:

>>> os.getcwd()
'C:\\Users\\estef\\AppData\\Local\\Programs\\Python\\Python38-32'

Este es el camino absoluto hacia mi directorio de trabajo actual:

'C:\\Users\\estef\\AppData\\Local\\Programs\\Python\\Python38-32'

En un programa

Si ejecutamos este comando desde un programa de Python, de esta forma:

import os
print(os.getcwd())

Veremos lo siguiente:

C:\Users\estef\Documents\freeCodeCamp\freeCodeCamp News\listdir vs system

El camino completo hasta el programa (su ubicación en el sistema, en la jerarquía de directorios).

💡 Dato: si ejecutas un programa (un archivo de Python), tu directorio de trabajo actual es el directorio del archivo que se está ejecutando.

Cómo cambiar tu directorio de trabajo actual

Puedes cambiar tu directorio de trabajo actual con el siguiente comando del módulo os:

os.chdir(<camino>)

Tendrás que especificar el camino (también llamado "ruta") al nuevo directorio de trabajo, pasándolo como un argumento en formato de cadena de caracteres. Puede ser un camino absoluto o relativo.

💡 Dato:

  • Un camino absoluto especifica toda la secuencia de directorios que deberás recorrer para alcanzar el directorio final. Este tipo de camino inicia desde el directorio raíz de tu sistema.

Por ejemplo:

>>> import os
>>> os.chdir(r"C:\Users\estef\Documents\freeCodeCamp\freeCodeCamp News\9 - listdir vs system")

# Verificar el directorio de trabajo actual.
>>> os.getcwd()
'C:\\Users\\estef\\Documents\\freeCodeCamp\\freeCodeCamp News\\9 - listdir vs system'

Nota que añadí una r antes del camino absoluto para convertir la cadena de caracteres en una cadena raw (cruda en español).

Si usas \ en la cadena de caracteres pero no añades la r, se generará un error porque el símbolo \ será tratado como un carácter especial.

De forma alternativa, podemos reemplazar las barras invertidas \ con barras inclinadas / en la cadena de caracteres que representa el camino:

>>> os.chdir("C:/Users/estef/Documents/freeCodeCamp/freeCodeCamp News/9 - listdir vs system")

# Verificar el directorio de trabajo actual.
>>> os.getcwd()
'C:\\Users\\estef\\Documents\\freeCodeCamp\\freeCodeCamp News\\9 - listdir vs system'
  • Un camino relativo especifica el camino que se debe recorrer para llegar a un directorio, pero ahora el camino inicia desde tu directorio de trabajo actual. Es más corto y más sencillo que el camino absoluto.

Por ejemplo, si tu directorio de trabajo actual contiene un subdirectorio (carpeta) Directorio 1, puedes moverte a este directorio usando un camino relativo (puedes imaginarlo como una carpeta dentro de otra carpeta y nos adentramos en esta jerarquía), de esta forma:

>>> import os
>>> os.chdir(".\Directorio 1")

# Verificar el directorio de trabajo actual.
>>> os.getcwd()
'C:\\Users\\estef\\Documents\fFreeCodeCamp\\freeCodeCamp News\\9 - listdir vs system\\Directorio 1'

💡 Dato: el punto al principio del camino relativo .\Directorio 1 representa el directorio de trabajo actual. Escribimos dos puntos ( ..) para subir en la jerarquía, es decir, para ir al directorio que contiene al directorio actual.

Ahora que ya tienes todo el conocimiento previo que necesitas para entender verdaderamente cómo funcionan listdir y system, veámoslas en detalle.

🔹 Listdir

Comenzaremos con la función listdir. Revelemos sus misterios.

Propósito y uso

Según la documentación de Python, esta función:

Retorna una lista que contiene los nombres de las entradas en el directorio dado por path.

Básicamente, retorna una lista con los nombres de los archivos y directorios que actualmente están en un directorio en particula. Este directorio es especificado al momento de llamar a la función.

💡 Dato: la lista no tendrá un order específico, incluso si normalmente ordenas los elementos alfabéticamente.

Sintaxis y parámetros

Para llamar a listdir, debemos usar esta sintaxis:

image-9

El parámetro camino es precisamente eso, el camino absoluto o relativo al directorio que quieres visualizar. A partir de Python 3.2, este parámetro es opcional. Por defecto, el camino llevará al directorio de trabajo actual si no pasas un argumento.  

image-12

Recuerda que debes importar el módulo os antes de llamar a esta función.

💡 Dato: si usas la sentencia de importación from os import listdir para importar la función de forma individual, puedes omitir os., de esta forma:

Screen-Shot-2022-10-22-at-10.29.45-AM

Usos y ventajas

La función listdir es muy útil porque funciona en cualquier sistema operativo en el cual se pueda ejecutar Python, así que si tienes Python instalado en tu dispositivo, esta función podrá ejecutarse.

Valor retornado

Ahora hablemos un poco sobre el valor que retorna. Como retorna una lista, podemos guardar esta lista en una variable y trabajar con ella en nuestro programa.

Por ejemplo, digamos que queremos hacer algo específico con todos los archivos de un directorio, como convertir imágenes a blanco y negro o modificar su contenido. Podríamos hacerlo con un ciclo for, de esta forma:

imagenes = os.listdir(<camino>)

for imagen in imagenes:
    # Hacer algo con la imagen

Claro, debes definir lo que ocurrirá dentro del ciclo, pero este es un ejemplo de lo que podrías lograr con esta función.

Asombroso, ¿cierto?

Pero tener archivos y directorios en la misma lista puede ser problemático si queremos trabajar con un ciclo for, ¿no? Necesitaríamos añadir un condicional para verificar el tipo de dato de cada elemento.

¿Cómo podemos crear una lista que solo contenga nombres de archivos (sin directorios) o viceversa?

¡Veamos! ✨

Solo incluir archivos

Si quieres "filtrar" la lista retornada por os.listdir() para que solo incluya archivos (sin directorios), puedes incluir esta línea de código:

list(filter(os.path.isfile, os.listdir(<camino>)))

💡 Dato: Puedes personalizar el argumento <camino> u omitirlo si deseas usar tu directorio de trabajo actual.

Veamos un ejemplo de mi directorio de trabajo actual:

# Estructura de mi directorio de trabajo actual
|- Directorio 1
|- Directorio 2
|- Diagrama.ppt
|- listdir vs system.png
|- script.py

Mi directorio (carpeta) tiene:

  • Dos subdirectorios (carpetas dentro de la misma carpeta).
  • Un archivo de PowerPoint.
  • Una imagen (archivo .png).
  • Un programa de Python.

Si llamo a la función listdir desde el archivo script.py y muestro la lista retornada:

print(os.listdir())

Este es el resultado:

['Diagrama.ppt', 'Directorio 1', 'Directorio 2', 'listdir vs system.png', 'script.py']

Puedes ver que todos los archivos y directorios de mi directorio de trabajo actual fueron incluidos.

Para filtrar esta lista de tal forma que solo contenga archivos, podemos usar esta línea de código:

print(list(filter(os.path.isfile, os.listdir())))

Ahora el resultado es:

['Diagrama.ppt', 'listdir vs system.png', 'script.py']

Nota cómo los directorios fueron "filtrados", exactamente lo que queríamos.

Solo incluir directorios

De igual forma, si deseas "filtrar" la lista para solo incluir directorios, puedes usar esta línea de código:

list(filter(os.path.isdir, os.listdir(<path>)))

Ahora el resultado es:

['Directorio 1', 'Directorio 2']

Exactamente lo que esperábamos. ¿Pero cómo funciona esta sentencia detrás de escenas? Veamos.

Cómo funciona filter() detrás de escenas

Para llamar a la función filter, usamos la siguiente sintaxis:

filter(<función>, <lista>)

Básicamente "filtra" los elementos del segundo argumento (la lista) en base al valor de verdad retornado por llamar a la función que pasamos como primer argumento (os.path.isfile() o os.path.isdir() en sus líneas de código respectivas):

print(list(filter(os.path.isfile, os.listdir())))
list(filter(os.path.isdir, os.listdir()))

Estas dos funciones:

os.path.isfile(<camino>)

os.path.isdir(<camino>)

Retornan True si el argumento es un archivo o un directorio, respectivamente.

En base a estos valores de verdad, los elementos de la lista serán incluidos (o no) en la lista final filtrada. Los elementos de la lista retornados por os.listdir() se pasan uno por uno a estas funciones para verificar si son archivos (o directorios, respectivamente).

Por ejemplo, si tengo la siguiente línea de código:

filter(os.path.isfile, os.listdir())))

Y os.listdir() retorna esta lista:

['Diagrama.ppt', 'Directorio 1', 'Directorio 2', 'script.py']

El primer elemento de la lista ('Diagrams.ppt') se pasa como argumento a os.path.isfile() para verificar si es un archivo:

os.path.isfile('Diagrama.ppt') # True
image-30

La llamada a la función retorna True, así que es un archivo y se incluye en la lista.

Pero si el elemento es un directorio:

os.path.isfile('Directory 1') # False
image-31

La llamada a la función retorna False, así que no se incluye en la lista. Este proceso continúa para cada elemento de la lista hasta que la lista nueva solo contiene los nombres de los archivos.

Luego, como filter() retorna un iterable, creamos una lista a partir de ese iterable con list():

list(filter(os.path.isfile, os.listdir()))

Y la podemos mostrar con print() porque que estamos trabajando con un programa de Python:

print(list(filter(os.path.isfile, os.listdir())))

💡 Dato: puedes identificar visualmente si un elemento de la lista representa un archivo o un directorio al ver si tiene una extensión (tipo de archivo) luego de su nombre. Por ejemplo: Diagrama.ppt tiene una extensión .ppt que nos dice que es un archivo de PowerPoint pero un directorio no tiene una extensión, como 'Directorio 1'.

image-32

🔸 System("ls")

¡Genial! Ahora que ya sabes cómo trabajar con listdir, veamos cómo funciona la función system() detrás de escenas y cómo la puedes usar.  

Propósito

Según la documentación de Python, el propósito de la función system() es:

Ejecutar el comando (una cadena) en una subcapa.

Básicamente, esta función toma un comando (una cadena de caracteres) y lo ejecuta.

En este caso, el comando que estamos pasando como argumento es 'ls', un comando Unix usado en Linux para mostrar el contenido de un directorio como output estándar.

A diferencia de listdir, la función system() no retorna una lista si pasamos el comando 'ls'.

Solo mostrará la lista de archivos y directorios como output estándar. Por lo tanto, deberías usarla solo si quieres visualizar la lista sin trabajar con ella en el programa.

Sintaxis y parámetros

Para llamar a esta función, debes usar la siguiente sintaxis:

image-15

Su único argumento es el comando que deseas ejecutar pero este argumento debe pasarse como una cadena de caracteres (rodeado por comillas dobles o simples).

Específicamente, el comando ls te permite ver el contenido de tu directorio de trabajo actual.

Por ejemplo: si este es mi directorio de trabajo actual (tres archivos de Python y un subdirectorio):

# Estructura de mi directorio de trabajo actual.
|- main.py
|- Directorio 1
|- archivo1.py
|- archivo2.py

Y llamo a la función system(), de esta forma:

>>> import os
>>> os.system("ls")

Este es el resultado:

'Directorio 1'  'archivo1.py'  'archivo2.py'   main.py
0

Podemos ver el resultado o output estándar en la consola (la lista de archivos y directorios):

'Directorio 1'  'archivo1.py'  'archivo2.py'   main.py

Y el valor retornado:

0

💡 Dato: para estos ejemplos de la función system(), estoy trabajando con una línea de comandos online llamada replit.com, ya que mi computadora tiene Windows instalado y el comando ls no se reconoce por defecto en el Command Prompt.

Limitaciones

Una de las principales limitaciones de esta función es que el comando que se pasa como argumento debe ser reconocido por el sistema operativo o ambiente en el cual estás trabajando.

Por ejemplo, el comando ls no será reconocido en Windows por defecto en el Command Prompt. Verás este error si intentas ejecutarlo:

'ls' is not recognized as an internal or external command, operable program or batch file.

Un comando similar en Windows sería el comando 'dir':

os.system('dir')

💡 Dato: existen formas alternativas para ejecutar el comando ls en Windows, como usar programas de terminal o de línea de comandos que reconozcan comandos Unix, pero por defecto Windows no reconoce el comando 'ls'.

Valor retornado

Según la documentación de Python:

En Unix, el valor de retorno es el estado de salida del proceso codificado en el formato especificado para wait().

Y...

En Windows, el valor de retorno es el que retorna el shell del sistema después de ejecutar command.

💡 Dato: nota que esta función no retorna una lista. Solo muestra la lista como output estándar, así que no podemos guardarla en una variable como hicimos anteriormente con la función listdir.

Variaciones del comando ls

Una característica muy importante de os.system('ls') es que tiene muchas opciones útiles e interesantes para personalizar cómo se presenta el output.

Veamos algunas de estas opciones.

Opción 1:
Podemos mostrar más información sobre archivos y directorios. Por ejemplo, su tamaño, ubicación y la fecha y hora en la cual fueron modificados con el comando ls -l.

>>> import os
>>> os.system('ls -l')
total 12
drwxr-xr-x 1 runner runner  0 Apr  3 18:23 'Directorio 1'
-rw-r--r-- 1 runner runner 11 Apr  3 18:38 'archivo1.py'
-rw-r--r-- 1 runner runner 11 Apr  3 18:38 'archivo2.py'
-rw-r--r-- 1 runner runner 11 Apr  3 18:38  main.py
0

Opción 2:
Para poder reconocer más rápidamente y de forma visual los directorios, podemos usar el comando ls -F, el cual agrega una barra inclinada / al final de sus nombres (por ejemplo 'Directory 1/' en el siguiente ejemplo).

>>> import os
>>> os.system('ls -F')
'Directorio 1'/  'archivo1.py'  'archivo2.py'   main.py
0

Opción 3:
Para ordenar los archivos por tamaño, podemos usar el comando ls -lS.

>>> import os
>>> os.system('ls -lS')
total 12
-rw-r--r-- 1 runner runner 11 Apr  3 18:38 'archivo1.py'
-rw-r--r-- 1 runner runner 11 Apr  3 18:38 'archivo2.py'
-rw-r--r-- 1 runner runner 11 Apr  3 18:38  main.py
drwxr-xr-x 1 runner runner  0 Apr  3 18:23 'Directorio 1'
0

Existen muchas opciones para personalizar el output que pueden ser útiles para tu meta en particular. Aquí puedes encontrar más información sobre el comando -ls y sobre cómo puedes usar todo su poder.

🔹 Resumen de listdir vs. system("ls")

  • Propósito: listdir retorna una lista con los nombres de los archivos y directorios en el camino especificado (por defecto, el directorio de trabajo actual) mientras que system("ls") solo los muestra como output estándar.
  • Sistema operativo: listdir puede ser usado independientemente del sistema operativo en el cual estés trabajando. En cambio, system('ls') debe ser ejecutado en un sistema operativo o ambiente que reconozca el comando 'ls'.
  • Personalización: puedes filtrar la lista retornada por listdir si necesitas remover archivos o directorio con la función filter() y puedes pasar opciones para personalizar el output de system('ls').

Espero que te haya gustado mi artículo y que te haya sido de utilidad. Ahora ya conoces las diferencias entre listdir y system('ls').

⭐ Te invito a seguirme en Twitter para encontrar más tutoriales y tips de programación.