Strings de Python

Python tiene una clase de cadena integrada llamada “str” con muchas funciones prácticas (existe un módulo antiguo llamado "string" que no deberías usar). Los literales de string pueden encerrarse entre comillas dobles o simples, aunque las comillas simples se usan con mayor frecuencia. Los escapes de barra invertida funcionan de la manera habitual dentro de literales de comillas simples y dobles, p.ej., \n \". Un literal de string entre comillas dobles puede contener comillas simples sin ningún problema (p.ej., “I don't do it”) y, asimismo, la string entre comillas simples puede contener comillas dobles. Un literal de string puede abarcar varias líneas, pero debe haber una barra inversa \ al final de cada línea para escapar la línea nueva. Literales de string dentro de comillas triples, “”” o “'” pueden abarcar varias líneas de texto.

Las cadenas de Python son “inmutables” lo que significa que no pueden modificarse una vez creadas (las cadenas de Java también usan este estilo inmutable). Dado que las cadenas no se pueden cambiar, construimos cadenas *nuevas* a medida que avanzamos para representar valores calculados. Así, por ejemplo, la expresión ("hello" + "there") toma las 2 cadenas "hello" y "allí" y compila una nueva cadena llamada “hellothere”.

Se puede acceder a los caracteres de una cadena con la sintaxis estándar [ ] y, al igual que Java y C++, Python usa indexación basada en cero, por lo que si s es "hello". s[1] es “e”. Si el índice está fuera de los límites de la string, Python genera un error. El estilo Python (a diferencia de Perl) consiste en detenerse si no puede decir qué hacer, en lugar de simplemente crear un valor predeterminado. La práctica "porción" la sintaxis (a continuación) también funciona para extraer cualquier subcadena de una cadena. La función len(string) muestra la longitud de una cadena. La sintaxis [ ] y la función len() en realidad funcionan en cualquier tipo de secuencia: cadenas, listas, etc. Python intenta que sus operaciones funcionen de manera coherente en diferentes tipos. Error común de Python para principiantes: no uses "len". como nombre de variable para evitar bloquear la función len(). el símbolo "+" puedes concatenar dos cadenas. Observa en el código siguiente que las variables no están declaradas previamente; simplemente asígnalas y listo.

  s = 'hi'
  print(s[1])          ## i
  print(len(s))        ## 2
  print(s + ' there')  ## hi there

A diferencia de Java, el símbolo "+" no convierte automáticamente números ni otros tipos en formato de cadena. La función str() convierte los valores en una forma de cadena para que puedan combinarse con otras cadenas.

  pi = 3.14
  ##text = 'The value of pi is ' + pi      ## NO, does not work
  text = 'The value of pi is '  + str(pi)  ## yes

Para los números, los operadores estándar, +, /, * funcionan de la forma habitual. No hay un operador ++, pero funciona +=, -=, etc. Si quieres realizar una división de números enteros, usa 2 barras diagonales, p.ej., 6 // 5 es 1

La impresión normalmente imprime uno o más elementos de Python seguidos de una línea nueva. Un producto "sin procesar" literal de string tiene el prefijo "r" y pasa todos los caracteres sin un tratamiento especial de las barras inversas, así que r'x\nx' da como resultado la cadena length-4 "x\nx". "imprimir" Puede aceptar varios argumentos para cambiar la forma en que imprime elementos (consulta la definición de la función de impresión de python.org), como configurar "end" a "" para dejar de imprimir una línea nueva cuando termina de imprimir todos los elementos.

  raw = r'this\t\n and that'

  # this\t\n and that
  print(raw)

  multi = """It was the best of times.
  It was the worst of times."""

  # It was the best of times.
  #   It was the worst of times.
  print(multi)

Métodos de cadenas

Estos son algunos de los métodos de cadena más comunes. Un método es como una función, pero se ejecuta “en” un objeto. Si la variable s es una cadena, el código s.lower() ejecuta el método lower() en ese objeto de la cadena y muestra el resultado (esta idea de un método que se ejecuta en un objeto es una de las ideas básicas que conforman la programación orientada a objetos, OOP). Estos son algunos de los métodos de cadena más comunes:

  • s.lower(), s.upper(): muestra la versión de la cadena en minúsculas o mayúsculas.
  • s.strip(): muestra una cadena sin espacios en blanco del principio y del final.
  • s.isalpha()/s.isdigit()/s.isspace()... -- comprueba si todos los caracteres de la cadena están en las distintas clases de caracteres.
  • s.startswith('other'), s.endswith('other') -- Comprueba si la cadena comienza o termina con la otra cadena dada.
  • s.find('other'): Busca la otra cadena dada (no una expresión regular) dentro de s y muestra el primer índice donde comienza o -1 si no se encuentra.
  • s.replace('old', 'new'): muestra una cadena donde aparecen todas las apariciones de "old" se reemplazó por 'nuevo'
  • s.split('delim'): Muestra una lista de subcadenas separadas por el delimitador dado. El delimitador no es una expresión regular, es solo texto. 'aaa,bbb,ccc'.split(',') -> ['aaa', 'bbb', 'ccc']. Como un caso especial conveniente, s.split() (sin argumentos) se divide en todos los caracteres de espacios en blanco.
  • s.join(list) -- opuesta a split(), une los elementos en la lista dada usando la cadena como delimitador. p.ej., '---'.join(['aaa', 'bbb', 'ccc']) -> aaa---bbb---ccc

Búsqueda en Google de “python str” te debería redireccionar a los métodos de cadena de python.org oficiales, que enumeran todos los métodos str.

Python no tiene un tipo de carácter independiente. En cambio, una expresión como s[8] muestra una longitud de string-1 que contiene el carácter. Con esa string-length-1, los operadores ==, <=, ... todos funcionan como esperabas, por lo que no es necesario saber que Python no tiene un "char" escalar independiente. el tipo de letra.

Porciones de cadena

La “porción” La sintaxis es una forma práctica de referirse a las subpartes de las secuencias, por lo general, cadenas y listas. La porción s[start:end] son los elementos que comienzan en el inicio y se extienden hasta el final, pero sin incluirlo. Supongamos que s = “Hello”

la cadena &quot;hello&quot; con índices de letras 0 1 2 3 4

  • s[1:4] es “ell” -- caracteres que comienzan en el índice 1 y se extienden hasta el índice 4, pero no lo incluyen
  • s[1:] es “ello” -- Omitir cualquiera de los índices tiene como valor predeterminado el inicio o el final de la cadena
  • s[:] es “Hola” -- Omitir ambos siempre nos da una copia de toda la información (esta es la forma pythonic de copiar una secuencia como una cadena o una lista)
  • s[1:100] es “ello” -- un índice demasiado grande se trunca a la longitud de la cadena

Los números de índice estándar basados en cero brindan un acceso fácil a los caracteres cerca del comienzo de la string. Como alternativa, Python usa números negativos para facilitar el acceso a los caracteres al final de la cadena: s[-1] es el último carácter 'o', s[-2] es 'l'. el que pasa al último carácter, y así sucesivamente. Los números de índice negativos se cuentan desde el final de la cadena:

  • s[-1] es “o” -- último carácter (primero desde el final)
  • s[-4] es “e” -- 4 desde el final
  • s[:-3] es 'Él' , que abarca hasta los últimos tres caracteres, pero no incluye.
  • s[-3:] es “llo” Comienza con el tercer carácter desde el final y se extiende hasta el final de la cadena.

Es una clara verdad de slices que para cualquier índice n, s[:n] + s[n:] == s. Esto funciona incluso para n negativos o fuera de los límites. O, en otras palabras, s[:n] y s[n:] siempre particionan la cadena en dos partes de cadena y conservan todos los caracteres. Como veremos más adelante en la sección de lista, los segmentos también funcionan con las listas.

Formato de cadenas

Algo interesante que puede hacer Python es convertir automáticamente los objetos en una cadena adecuada para imprimir. Dos formas integradas de hacerlo son las cadenas con formato literales, también llamados “cadenas f”, e invocar str.format().

Literales de cadena con formato

A menudo, verás literales de cadena con formato que se usan en situaciones como las siguientes:

  value = 2.791514
  print(f'approximate value = {value:.2f}')  # approximate value = 2.79

  car = {'tires':4, 'doors':2}
  print(f'car = {car}') # car = {'tires': 4, 'doors': 2}

Una cadena literal con formato tiene el prefijo "f" (como el prefijo 'r' que se usa para cadenas sin procesar). Cualquier texto fuera de las llaves "{}" se imprime directamente. Expresiones contenidas en "{}" son se imprimen con la especificación de formato descrita en la especificación de formato. Hay muchas cosas buenas que se pueden hacer con el formateo, incluidos el truncamiento y conversión a notación científica y alineación horizontal, izquierda y derecha.

Las cadenas f son muy útiles cuando quieres imprimir una tabla de objetos y quieres las columnas que representan los diferentes atributos del objeto que se deben alinear, como

  address_book = [{'name':'N.X.', 'addr':'15 Jones St', 'bonus': 70},
      {'name':'J.P.', 'addr':'1005 5th St', 'bonus': 400},
      {'name':'A.A.', 'addr':'200001 Bdwy', 'bonus': 5},]

  for person in address_book:
    print(f'{person["name"]:8} || {person["addr"]:20} || {person["bonus"]:>5}')

  # N.X.     || 15 Jones St          ||    70
  # J.P.     || 1005 5th St          ||   400
  # A.A.     || 200001 Bdwy          ||     5

% de cadena

Python también tiene una instalación antigua similar a printf() para armar una cadena. El operador % toma una cadena de formato de tipo printf a la izquierda (%d int, %s string, %f/%g punto flotante) y los valores coincidentes en una tupla a la derecha (una tupla está formada por valores separados por comas, generalmente agrupados entre paréntesis):

  # % operator
  text = "%d little pigs come out, or I'll %s, and I'll %s, and I'll blow your %s down." % (3, 'huff', 'puff', 'house')

La línea anterior es bastante larga. Supongamos que quieres dividirla en líneas separadas. No se puede dividir la línea después del '%' como lo harías en otros lenguajes, ya que, de forma predeterminada, Python trata cada línea como una instrucción independiente (la ventaja es que no es necesario escribir punto y coma en cada línea). Para solucionar este problema, encierra toda la expresión en un conjunto externo de paréntesis, luego se permite que la expresión abarque varias líneas. Esta técnica de código entre líneas funciona con las diversas construcciones de agrupación que se detallan a continuación: ( ), [ ], { }.

  # Add parentheses to make the long line work:
  text = (
    "%d little pigs come out, or I'll %s, and I'll %s, and I'll blow your %s down."
    % (3, 'huff', 'puff', 'house'))

Eso está mejor, pero la fila aún es un poco larga. Python te permite cortar una línea en partes, que luego concatenará automáticamente. Por lo tanto, para acortar aún más esta línea, podemos hacer lo siguiente:

  # Split the line into chunks, which are concatenated automatically by Python
  text = (
    "%d little pigs come out, "
    "or I'll %s, and I'll %s, "
    "and I'll blow your %s down."
    % (3, 'huff', 'puff', 'house'))

Strings (Unicode frente a bytes)

Las cadenas regulares de Python son Unicode.

Python también admite cadenas compuestas por bytes sin formato (indicados por el prefijo “b” delante de un literal de string). como:

> byte_string = b'A byte string'
> byte_string
  b'A byte string'

Una cadena Unicode es un tipo diferente de objeto de una cadena de bytes, pero hay varias bibliotecas, como Las expresiones regulares funcionan correctamente si se pasan cualquiera de los tipos de cadena.

Para convertir una cadena normal de Python en bytes, llama al método encode() en la cadena. En la dirección opuesta, el método decode() de cadena de bytes convierte bytes sin formato codificados en una cadena Unicode:

> ustring = 'A unicode \u018e string \xf1'
> b = ustring.encode('utf-8')
> b
b'A unicode \xc6\x8e string \xc3\xb1'  ## bytes of utf-8 encoding. Note the b-prefix.
> t = b.decode('utf-8')                ## Convert bytes back to a unicode string
> t == ustring                         ## It's the same as the original, yay!

True

En la sección de lectura de archivos, hay un ejemplo que muestra cómo abrir un archivo de texto con algo de codificación y leer cadenas Unicode.

Sentencia if

Python no usa { } para encerrar bloques de código para if/loops/function, etcétera. En cambio, Python usa dos puntos (:) y la sangría o el espacio en blanco para agrupar sentencias. La prueba booleana de un elemento if no necesita estar entre paréntesis (gran diferencia de C++/Java), y puede tener cláusulas *elif* y *else* (mnemotécnica: la palabra "elif" tiene la misma longitud que la palabra "else").

Cualquier valor se puede usar como una prueba if. El “cero” todos los valores se cuentan como falsos: Ninguno, 0, cadena vacía, lista vacía, diccionario vacío. También hay un tipo booleano con dos valores: True y False (convertidos en int, estos son 1 y 0). Python tiene las operaciones de comparación habituales: ==, !=, <, <=, >, >=. A diferencia de Java y C, == se sobrecarga para funcionar correctamente con cadenas. Los operadores booleanos son las palabras *y*, *o*, *no* (Python no usa el símbolo C de estilo && || !). Así es como se vería el código para una app de salud que proporciona recomendaciones de bebidas a lo largo del día. Observa cómo cada bloque de sentencias "entonces" y "si no" comienza con un ":", y las instrucciones están agrupadas por su sangría:

  if time_hour >= 0 and time_hour <= 24:
    print('Suggesting a drink option...')
    if mood == 'sleepy' and time_hour < 10:
      print('coffee')
    elif mood == 'thirsty' or time_hour < 2:
      print('lemonade')
    else:
      print('water')

Creo que omitir el “:” es mi error de sintaxis más común cuando escribo el tipo de código anterior, probablemente ya que eso es algo adicional que escribir en comparación con mis hábitos de C++/Java. Tampoco pongas la prueba booleana entre paréntesis, eso es un hábito de C/Java. Si el código es corto, puedes colocarlo en la misma línea después de ":", como se indica aquí (también se aplica a funciones, bucles, etc.), aunque algunas personas sienten que es más fácil espaciar los elementos en líneas separadas.

  if time_hour < 10: print('coffee')
  else: print('water')

Ejercicio: string1.py

Para practicar el material de esta sección, prueba el ejercicio string1.py en los Ejercicios básicos.