Para generar una nueva lista a partir de una lista (array) cuyos elementos son cadenas, extrayendo sólo los elementos de las cadenas que satisfacen ciertas condiciones, o realizando sustituciones, conversiones, etc., utilice las comprensiones de listas.
Tras una breve explicación de las comprensiones de listas, se explican los siguientes contenidos con código de ejemplo.
- Extracción basada en la inclusión o no de una cadena específica (coincidencia parcial)
- Reemplazar cadena específica
- Extraer comenzando o no con una cadena específica
- Extraer terminando o no con una cadena específica
- Juzgado y extraído por caso
- Convertir mayúsculas y minúsculas
- Determina si se utilizan caracteres alfabéticos o numéricos y los extrae
- Múltiples condiciones
- expresión regular (informática)
Tenga en cuenta que las listas pueden almacenar diferentes tipos de datos y son estrictamente diferentes de los arrays. Si quieres manejar arrays en procesos que requieren tamaño de memoria y direcciones de memoria o procesamiento numérico de grandes datos, utiliza array (biblioteca estándar) o NumPy.
- notación de inclusión en la lista
- Contiene una cadena específica (coincidencia parcial) \N – No contiene: in
- Reemplazar cadena específica
- Empieza con una cadena específica \N y no empieza: startswith()
- Termina con una cadena de caracteres específicos \ ~ no termina: endswith()
- Juzgado y extraído por caso
- Convertir mayúsculas y minúsculas
- Determina si se utilizan caracteres alfabéticos o numéricos y los extrae
- Múltiples condiciones
- expresión regular (informática)
notación de inclusión en la lista
Cuando se genera una nueva lista a partir de una lista, las comprensiones de lista son más sencillas de escribir que los bucles for.
[expression for any variable name in iterable object if conditional expression]
Si el elemento sólo debe ser seleccionado por una expresión condicional, no es procesado por una expresión, por lo que toma la siguiente forma
[variable name for variable name in original list if conditional expression]
Si la expresión condicional if se convierte en una expresión condicional if not, se convierte en una negación, y se pueden extraer los elementos que no satisfacen la expresión condicional.
Contiene una cadena específica (coincidencia parcial) \N – No contiene: in
En «cadena específica en cadena original», devuelve True si la cadena original contiene la cadena específica. Se trata de una expresión condicional.
La negación de in se hace con not in.
l = ['oneXXXaaa', 'twoXXXbbb', 'three999aaa', '000111222']
l_in = [s for s in l if 'XXX' in s]
print(l_in)
# ['oneXXXaaa', 'twoXXXbbb']
l_in_not = [s for s in l if 'XXX' not in s]
print(l_in_not)
# ['three999aaa', '000111222']
Reemplazar cadena específica
Si desea reemplazar una cadena de elementos de la lista, utilice el método replace() para cada elemento de la notación de comprensión de la lista.
Si no hay ninguna cadena que reemplazar, no es necesario seleccionar el elemento en la expresión condicional if porque no se modificará al aplicar replace().
l_replace = [s.replace('XXX', 'ZZZ') for s in l]
print(l_replace)
# ['oneZZZaaa', 'twoZZZbbb', 'three999aaa', '000111222']
Si quiere reemplazar un elemento entero que contiene una cadena específica, extráigala con in y procésela con el operador ternario. El operador ternario se escribe de la siguiente forma.True Value if Conditional Expression else False Value
Está bien si la parte de expresión de la notación de comprensión de la lista es un operador ternario.
l_replace_all = ['ZZZ' if 'XXX' in s else s for s in l]
print(l_replace_all)
# ['ZZZ', 'ZZZ', 'three999aaa', '000111222']
A continuación se presenta un resumen de los resultados, entre paréntesis. Si no está acostumbrado a utilizar paréntesis, puede ser más fácil de entender y evitar errores. Gramaticalmente, no hay ningún problema aunque se escriban paréntesis.
[('ZZZ' if ('XXX' in s) else s) for s in l]
El uso de in como condición es confuso con la notación de comprensión de listas in, pero no es difícil si se conoce la forma sintáctica de la notación de comprensión de listas y los operadores ternarios.
Empieza con una cadena específica \N y no empieza: startswith()
El método de cadena startswith() devuelve true si la cadena comienza con la cadena especificada en el argumento.
l_start = [s for s in l if s.startswith('t')]
print(l_start)
# ['twoXXXbbb', 'three999aaa']
l_start_not = [s for s in l if not s.startswith('t')]
print(l_start_not)
# ['oneXXXaaa', '000111222']
Termina con una cadena de caracteres específicos \ ~ no termina: endswith()
El método de cadena endswith() devuelve true si la cadena termina con la cadena especificada en el argumento.
l_end = [s for s in l if s.endswith('aaa')]
print(l_end)
# ['oneXXXaaa', 'three999aaa']
l_end_not = [s for s in l if not s.endswith('aaa')]
print(l_end_not)
# ['twoXXXbbb', '000111222']
Juzgado y extraído por caso
Los métodos de cadena isupper(),islower() pueden utilizarse para determinar si una cadena es toda mayúscula o toda minúscula.
l_lower = [s for s in l if s.islower()]
print(l_lower)
# ['three999aaa']
Convertir mayúsculas y minúsculas
Si desea convertir todos los caracteres en mayúsculas o minúsculas, utilice los métodos de cadena upper() y lower(). Otros métodos son capitalize(), que sólo pone en mayúsculas la primera letra, y swapcase(), que intercambia las mayúsculas y las minúsculas.
Al igual que en el ejemplo de sustitución anterior, utilice el operador ternario si desea procesar sólo los elementos que cumplen la condición.
l_upper_all = [s.upper() for s in l]
print(l_upper_all)
# ['ONEXXXAAA', 'TWOXXXBBB', 'THREE999AAA', '000111222']
l_lower_to_upper = [s.upper() if s.islower() else s for s in l]
print(l_lower_to_upper)
# ['oneXXXaaa', 'twoXXXbbb', 'THREE999AAA', '000111222']
Determina si se utilizan caracteres alfabéticos o numéricos y los extrae
Los métodos de cadena isalpha() y isnumeric() pueden utilizarse para determinar si una cadena es totalmente alfabética, numérica, etc.
l_isalpha = [s for s in l if s.isalpha()]
print(l_isalpha)
# ['oneXXXaaa', 'twoXXXbbb']
l_isnumeric = [s for s in l if s.isnumeric()]
print(l_isnumeric)
# ['000111222']
Múltiples condiciones
La parte de la expresión condicional de las comprensiones de listas puede ser de múltiples condiciones. También se pueden utilizar condiciones negativas «no».
Cuando se utilizan tres o más expresiones condicionales, es más seguro encerrar cada grupo entre paréntesis () porque el resultado variará dependiendo del orden.
l_multi = [s for s in l if s.isalpha() and not s.startswith('t')]
print(l_multi)
# ['oneXXXaaa']
l_multi_or = [s for s in l if (s.isalpha() and not s.startswith('t')) or ('bbb' in s)]
print(l_multi_or)
# ['oneXXXaaa', 'twoXXXbbb']
expresión regular (informática)
Las expresiones regulares permiten un procesamiento muy flexible.
El objeto de coincidencia devuelto por re.match() cuando coincide se determina siempre como verdadero cuando se evalúa con una expresión condicional. Si no coincide, devuelve None, que es falso en la expresión condicional. Por lo tanto, si quiere extraer sólo los elementos que coinciden con la expresión regular, sólo tiene que aplicar re.match() a la parte de la expresión condicional de la expresión de comprensión de la lista como antes.
import re
l = ['oneXXXaaa', 'twoXXXbbb', 'three999aaa', '000111222']
l_re_match = [s for s in l if re.match('.*XXX.*', s)]
print(l_re_match)
# ['oneXXXaaa', 'twoXXXbbb']
re.sub(), que sustituye la parte coincidente de una expresión regular, también es útil. Para extraer y reemplazar sólo los elementos coincidentes, basta con añadir «expresión condicional if».
l_re_sub_all = [re.sub('(.*)XXX(.*)', r'\2---\1', s) for s in l]
print(l_re_sub_all)
# ['aaa---one', 'bbb---two', 'three999aaa', '000111222']
l_re_sub = [re.sub('(.*)XXX(.*)', r'\2---\1', s) for s in l if re.match('.*XXX.*', s)]
print(l_re_sub)
# ['aaa---one', 'bbb---two']