Las listas son un tipo de colección que hereda de la interface collection, son una estructura de datos que respeta el orden en el cual fueron agregados los elementos, también permiten registros repetidos. Todos los lenguajes de programación deben trabajar con colecciones de datos a los que cada cual significa con su propia nomenclatura: matrices, arrays, etc. Este artículo explorará la creación y manipulación de listas de cadenas, con un enfoque en C# y Python.
Listas de Cadenas en C#
Las listas en C# (C# lists) son un tipo de datos nativo del framework de .NET que nos permite almacenar una secuencia de variables. C# tiene un amplio rango de clases para lidear con listas. Implementando la interfaz de iList y la implementación mas popular es la lista generica, normalmente referida como List
Es decir, cuando creamos una lista le podemos decir qué tipo de objetos va contener (strings, números, o tipo T). Cuando hablamos de tipo «T», nos referimos a cualquier tipo de objetos que hayamos definido en nuestro código fuente. La "T" especifica el tipo de objeto contenido en la lista, el cual tiene el beneficio añadido de que el compliador verificará y se asegurará que se agreguen unicamente objetos del tipo de la lista - en otras palabras la lista tipo -List
ListpersonNames;
Inicialización de una Lista de Cadenas
Para inicializar una lista en C#, es tan sencillo como utilizar la keyword List, seguido del tipo de dato que va a contener dicha lista entre los símbolos <>. A continuación, debemos utilizar el constructor de List como si de cualquier otro objeto C# se tratase:
ListpersonNames = new List ();
Una vez hemos construido nuestro objeto Lista, ya podemos comenzar a utilizarla. En los ejemplos anteriores ya hemos visto una de las dos formas de añadir elementos a una lista en C#. Sin embargo, C# realmente le permite crear una lista Y agregarle elementos dentro de la misma declaración, utilizando una técnica llamada inicializadores de colección.
Lea también: IVA 21% Excel
Veamos cómo se hace:
ListlistOfNames = new List (){ "John Doe", "Jane Doe", "Joe Doe"};
La sintaxis es bastante simple: antes del punto y coma final habitual, tenemos un conjunto de llaves, que a su vez contiene una lista de los valores que queremos que estén presentes en la lista desde el principio. Como se trata de una lista de strings, los objetos iniciales que proporcionamos deben ser del tipo de string. Otra forma muy legible de inicializar una lista en una única línea es utilizar el inicializador inline que nos proporciona el .NET framework:
ListmorePersonNames = new List () { "Persona 1", "Persona 2", "Persona 3"};
En este caso, hemos creado otra lista distinta a la que hemos añadido tres strings, utilizando la inicialización inline del objeto List.
Añadiendo Elementos a una Lista de Cadenas
La primera forma que vamos a ver consiste en usar la función Add del objeto List, y que añadirá el elemento al final de la lista.
personNames.Add("Kevin");personNames.Add("Borja");A partir de este momento, nuestra lista contiene dos elementos (Kevin y Borja).
Lea también: Guía IVA reducido
Pero si investigamos un poco en las funciones que nos permite usar el objeto List, tenemos otra forma de añadir elementos que es a través de la función Insert. En este caso, la función Insert también nos pide la posición (índice) donde queremos insertar el elemento. La diferencia es que, si bien el método Add siempre agrega al final de la lista, el método Insert le permite insertar un elemento en una posición específica.
Por ejemplo, si quisiéramos añadir un elemento al principio de nuestra lista de personNames, utilizaríamos la siguiente función:
personNames.Insert(0, "Pepito");
De esta forma, nuestra lista estaría formada por tres nombres: Pepito, Kevin y Borja (en este orden). Esto es importante si el orden de los elementos dentro de la lista es relevante.
Aquí hay un ejemplo con múltiples inserciones:
ListlistOfNames = new List (){ "Joe Doe"};// Insert at the top (index 0)listOfNames.Insert(0, "John Doe");// Insert in the middle (index 1)listOfNames.Insert(1, "Jane Doe");
El primer parámetro del método Insert es el índice donde queremos insertar el elemento. Sin embargo, tenga cuidado: se lanzará una excepción si intenta insertar un elemento en el índice 3, ¡si la lista tiene menos elementos!
Lea también: ¿Cómo localizar tus XML del SAT?
Añadiendo Múltiples Elementos
Al igual que tenemos los métodos Agregar e Insertar para agregar un solo elemento, también hay métodos correspondientes para agregar e insertar múltiples elementos. Se llaman AddRange() e InsertRange() y acepta cualquier tipo de colección que implemente la interfaz IEnumerable como parámetro; esto podría ser, p.e. una matriz de elementos u otra lista, qué elementos desea agregar o insertar en la lista actual.
Como ejemplo de los métodos Range, podemos combinar el método AddRange con un inicializador de colección para agregar varios nombres nuevos a una lista existente en una sola declaración:
listOfNames.AddRange(new string[] { "Jenna Doe", "Another Doe" });Simplemente creamos una serie de cadenas sobre la marcha e inmediatamente agregamos sus elementos a nuestra lista de nombres del ejemplo anterior.
Eliminando Elementos de una Lista de Cadenas
Actualmente hay tres métodos a su disposición cuando desea eliminar uno o varios elementos de una lista: Remove(), RemoveAt() y RemoveAll().
La primera y más sencilla forma es utilizar la función Remove que nos proporciona List. Le pasamos el elemento que queramos eliminar, y lo sacará de nuestra lista:
personNames.Remove("Pepito");De esta forma, al haber eliminado a Pepito de la lista de nombres, nos volvemos a quedar con dos elementos (Kevin y Borja).
Si a la función Remove le pasamos un parámetro que no exista en nuestra lista, no ocurre nada. Por ejemplo:
personNames.Remove("No existe!");Tras esta operación, nuestra lista de nombres seguirá conteniendo a Kevin y a Borja. El método Remove() toma solo un parámetro: el elemento que desea eliminar. El método Remove() simplemente recorre la lista en iteración hasta que encuentra la primera instancia del objeto que especificó para su eliminación, y ellos la eliminan; solo elimina una instancia, y si especifica un elemento en la lista que no existe, No se arroja ningún error. El método devuelve true si pudo eliminar un elemento y false si no lo fue.
La segunda forma de eliminar objetos de una lista es utilizar RemoveAt. En este caso, le diremos qué posición (índice) de la lista queremos eliminar. Por ejemplo, podría eliminar el primer elemento de la lista así:
listOfNames.RemoveAt(0);
Con esto, eliminaríamos el primer elemento de nuestra lista (Kevin), y tan solo nos quedaría un elemento (Borja). Nuevamente, esto solo elimina un solo elemento y esta vez, debe tener cuidado al proporcionar el índice del elemento que se eliminará; si utiliza un índice que está fuera de los límites (inferior a 0 o superior a la cantidad de elementos) se lanzará una excepción!
RemoveAll() es el más complejo de los métodos remove, pero definitivamente también el más poderoso. Toma un delegado a un método como parámetro y este método decide si un elemento debe eliminarse o no devolviendo verdadero o falso. Esto le permite aplicar su propia lógica al eliminar elementos y también le permite eliminar más de un elemento a la vez.
Aquí hay un ejemplo de uso de RemoveAll():
ListlistOfNames = new List (){ "John Doe", "Jane Doe", "Joe Doe", "Another Doe"};listOfNames.RemoveAll(name => { if (name.StartsWith("J")) return true; else return false;});
El método RemoveAll() usa esta respuesta (verdadero o falso) para decidir si cada elemento debe eliminarse o no. Al final, esto deja nuestra lista inicial con solo un miembro de Doe: Another Doe.
Trabajando con los Elementos de una Lista de Cadenas
Hay varias formas de trabajar con los elementos de una lista genérica y mostrar algunos de ellos. El List
He creado un ejemplo más amplio mostrando cómo iterar y acceder a elementos:
using System;using System.Collections.Generic;namespace Lists{ class Program { static void Main(string[] args) { List listOfUsers = new List() { new User() { Name = "John Doe", Age = 42 }, new User() { Name = "Jane Doe", Age = 34 }, new User() { Name = "Joe Doe", Age = 8 }, }; for(int i = 0; i < listOfUsers.Count; i++) { Console.WriteLine(listOfUsers[i].Name + " is " + listOfUsers[i].Age + " years old"); } Console.ReadKey(); } } class User { public string Name { get; set; } public int Age { get; set; } }} Una vez que tenemos lista la lista, utilizo un bucle for para ejecutarla - para saber cuántas iteraciones vamos a hacer, uso la propiedad Count de la lista. En cada iteración, accedo al usuario en cuestión a través del indexador de la lista, utilizando la sintaxis de corchetes (por ejemplo, listOfUsers [i]). Una vez que tengo el usuario, escribo el nombre y la edad.
Ordenando Elementos de Lista de Cadenas
En los ejemplos anteriores, comentamos que los elementos dentro de una lista ocupan la posición en la que se añadieron a través de las funciones Add o Insert. Esto es así, pero también existe la posibilidad de ordenar una lista de elementos a través de la función Sort. Esto ordenará los elementos de la lista en sentido ascendente (de la A a la Z en el caso de strings, o de más pequeño a más grande en el caso de números). El método Sort ordena todos los elementos de la lista en su orden normal (alfabéticamente para cadenas).
La List
ListlistOfNames = new List (){ "John Doe", "Jane Doe", "Joe Doe", "Another Doe"};listOfNames.Sort();foreach (string name in listOfNames) Console.WriteLine(name);
Como verá en la salida, los elementos de la lista ahora se han ordenado alfabéticamente, y si lo desea en orden descendente (de Z a A), simplemente llame al método Reverse() después de realizar la clasificación:
listOfNames.Sort();listOfNames.Reverse();
Por otro lado, es posible que tenga una lista de objetos personalizados (ya que la List
using System;using System.Collections.Generic;namespace ListSort{ class Program { static void Main(string[] args) { List listOfUsers = new List() { new User() { Name = "John Doe", Age = 42 }, new User() { Name = "Jane Doe", Age = 39 }, new User() { Name = "Joe Doe", Age = 13 }, }; listOfUsers.Sort(CompareUsers); foreach (User user in listOfUsers) Console.WriteLine(user.Name + ": " + user.Age + " years old"); } public static int CompareUsers(User user1, User user2) { return user1.Age.CompareTo(user2.Age); } } public class User { public string Name { get; set; } public int Age { get; set; } }} Esto agregó bastante código a nuestro ejemplo, pero en realidad no es demasiado complicado. En el medio, he declarado un método llamado CompareUsers(): toma dos usuarios como parámetros y luego devuelve un número entero, que indicará si un elemento es "más pequeño", "igual" o "más grande" (-1, 0 o 1). El método Sort() utilizará estos valores para mover los elementos de modo que el orden de los elementos coincida con lo que queremos. En este caso, simplemente uso la propiedad Age para comparar, esencialmente dejándonos con una lista de usuarios ordenados por su edad.
Resumen de Métodos Comunes en C# para List
La siguiente tabla resume algunos de los métodos más utilizados para manipular listas de cadenas en C#:
| Método/Propiedad | Descripción | Ejemplo |
|---|---|---|
| Add() | Añade un elemento al final de la lista. | lista.Add("NuevoElemento"); |
| Insert() | Inserta un elemento en una posición específica. | lista.Insert(0, "PrimerElemento"); |
| AddRange() | Añade los elementos de una colección al final. | lista.AddRange(new string[]{"A", "B"}); |
| Remove() | Elimina la primera ocurrencia de un elemento específico. | lista.Remove("ElementoViejo"); |
| RemoveAt() | Elimina un elemento en el índice especificado. | lista.RemoveAt(0); |
| RemoveAll() | Elimina todos los elementos que coinciden con una condición. | lista.RemoveAll(s => s.StartsWith("J")); |
| Sort() | Ordena los elementos de la lista. | lista.Sort(); |
| Reverse() | Invierte el orden de los elementos. | lista.Reverse(); |
| IndexOf() | Busca un elemento y devuelve el índice de la primera ocurrencia. | int index = lista.IndexOf("BuscarElemento"); |
| Count | Propiedad que obtiene el número de elementos. | int total = lista.Count; |
Listas de Cadenas en Python
En Python, las listas son objetos mutables, mientras que las cadenas son inmutables. El objeto lista es una secuencia ordenada de ninguna (lista vacía) o más 'referencias de objetos' (variables que apuntan a otros objetos de Python: enteros, decimales, cadenas, tuplas, otras listas, etc.). Las listas, como secuencias que son, son susceptibles de compararse empleando los consabidos operadores de comparación. Recordemos una vez más que una secuencia es mutable en tanto en cuanto sus elementos pueden ser indexados, esto es, llamados por sus índices.
Creación y Conversión de Cadenas a Listas
Por “Python string to list” se entiende la conversión de una cadena en una lista. La función Python list se utiliza para convertir distintas estructuras de datos, incluidas las cadenas, en listas. Esto se hace mediante la función list() de un iterable. A esta función list(), en el caso de que no le pasáramos argumento alguno, nos devuelve una lista vacía; con un argumento, nos devuelve una lista con una copia simple del argumento.
También podemos crear una lista directamente encapsulando una serie de objetos entre corchetes separados por comas unos de otros. En este ejemplo, x, y y z son listas homogéneas dado que todos los elementos son del mismo tipo(x, ints; y, strings; z, floats). La variable w acoge una lista heterogénea que aglutina una string, un int, un float y una tupla que, a su vez, contiene tres objetos de tipo string: "a", "b" y "c". Finalmente h es una lista que no contiene valores sino variables: x, y, z y w que señalan a las cuatro listas que acabamos de construir, es decir, una lista de listas.
El método Python split se encarga de dividir una cadena en una lista de subcadenas basándose en un separador o patrón específico. Los parámetros opcionales son:
- sep: es el separador en el que se divide la cadena.
- maxsplit: define el número máximo de divisiones que se van a realizar.
El string slicing o corte de cadena es otro de los métodos Python string to list. La función List Comprehension es una forma concisa de crear listas combinando bucles y condiciones en una sola línea de código. Un principio similar al del método anterior puede expresarse de manera compacta en la propia asignación de la lista, mediante la operación llamada comprensión de lista (list comprehension). La función convert(string) es una función personalizada que convierte una cadena en una lista de caracteres. En este caso, se ha utilizado la cadena "Hello World". A partir de ella se ha creado una lista y se ha almacenado en char_list.
Manipulación y Operaciones con Listas de Cadenas en Python
Las listas, list, admiten indexado y slicing, esto es, hacer rebanadas; verificación de elementos a través de los operadores in y not in; la identidad mediante los operadores is e is not; la longitud o tamaño mediante la función len(); las funciones min(), max() y sum(). Por medio de la función .insert() se puede insertar un elemento en una lista.
Las listas también pueden concatenarse, como las cadenas, usando el operador +. También podemos usar el operador +=, que sumará todos los elementos que se encuentren a la derecha del operador. Notemos como el resultado de utilizar el operador + y el operador += no es el mismo: con el operador + obtenemos una concatenación estándar, conocida y previsible con lo que hasta ahora hemos estudiado. Sin embargo, con el operador += obtenemos una lista a la que se ha añadido como ítems las listas b y c.
La función sorted() devuelve una lista ordenada de los elementos de la secuencia que recibe como argumento (lista o cadena). La función enumerate() es una función integrada de Python que sirve para obtener tanto el índice como el valor de cada elemento en una estructura de datos iterable.
El módulo ast (Abstract Syntax Trees) permite evaluar una cadena en una estructura de datos de Python en la que la cadena se interpreta como un literal de Python. JSON es un módulo que se utiliza para leer y escribir datos JSON y para convertir estructuras de datos Python en formato JSON y viceversa.
