Introducción a la programación en Python
clase 7

Métodos de cadenas de caracteres

Las cadenas de caracteres (strings) disponen de una gran cantidad de métodos. Hay que recordar que las cadenas de caracteres son inmutables, y por tanto ninguno de estos métodos modifica la cadena que recibe como argumento, sino que devuelve información de la misma (por ejemplo, una variable booleana), o una copia modificada.

s.join(seq)

Devuelve la concatenación de todos los elementos de la secuencia seq, separados por la cadena s.

In [1]:
lista = ["hola", "foo", "bar"]
cadena = " ".join(lista)
print(cadena)
cadena = ", ".join(lista)
print(cadena)
cadena = "\t".join(lista)
print(cadena)
hola foo bar
hola, foo, bar
hola	foo	bar

s.split(t, n)

Divide la cadena s un número n de veces, tomando t como separador. Ambos argumentos son opcionales: por defecto divide el máximo de veces tomando como separador la cadena vacía.

In [2]:
cadena = "buen día, Python"
print(cadena.split())
print(cadena.split(","))
print(cadena.split(" ", 1))
['buen', 'día,', 'Python']
['buen día', ' Python']
['buen', 'día, Python']

s.replace(viejo, nuevo [, maxreplace])

Reemplaza en la cadena s las apariciones de la cadena viejo por la cadena nuevo. Opcionalmente se puede determinar la cantidad máxima de veces a realizar la sustitución (por defecto sustituye todas las apariciones de la cadena).

In [3]:
s = "esto es foo, aquello es foo, y lo otro es foo"
print(s.replace("foo", "bar"))
print(s.replace("foo", "bar", 2))
print(s.replace("foo", "bar", 1))
esto es bar, aquello es bar, y lo otro es bar
esto es bar, aquello es bar, y lo otro es foo
esto es bar, aquello es foo, y lo otro es foo

Cambio de caja

Hay una serie de métodos específicos para procesar la caja (mayúsculas/minúsculas) de los caracteres de las cadenas:

s.capitalize() Devuelve una copia de la cadena s con el primer carácter en mayúsculas.
s.title() Devuelve una copia de la cadena s con el primer carácter de cada palabra en mayúsculas.
s.swapcase() Devuelve una copia de la cadena s cambiando la caja de cada carácter.
s.lower() Devuelve una copia de la cadena s cambiando todos los caracteres a minúsculas.
s.upper() Devuelve una copia de la cadena s cambiando todos los caracteres a mayúsculas.
In [4]:
cadena = "cambia la caja"
mayuscula = cadena.capitalize()
print(mayuscula)
titulo = mayuscula.title()
print(titulo)
cambio = titulo.swapcase()
print(cambio)
minusculas = cambio.lower()
print(minusculas)
mayusculas = minusculas.upper()
print(mayusculas)
Cambia la caja
Cambia La Caja
cAMBIA lA cAJA
cambia la caja
CAMBIA LA CAJA

Hay otro conjunto de métodos que verifican si una cadena posee cierta propiedad, y devuelve la variable booleana (True o False) correspondiente.

s.isalnum() Devuelve True (verdadero) si s no es vacía y todos sus caracteres son alfanuméricos.
s.isalpha()

Devuelve True (verdadero) si s no es vacía y todos sus caracteres son alfabéticos.

s.islower() Devuelve True (verdadero) si s tiene al menos un carácter con caja, y todos sus caracteres con caja son minúsculas.
s.isupper() Devuelve True (verdadero) si s tiene al menos un carácter con caja, y todos sus caracteres con caja son mayúsculas.
s.istitle()

Devuelve True (verdadero) si s no es vacía, y tiene un estilo de caja de título (ver además s.title()).

s.isnumeric() Devuelve True (verdadero) si s no es vacía, y todos sus caracteres son caracteres numéricos Unicode, tales como dígitos, fracciones, numerales, etc.
s.isdigit() Devuelve True (verdadero) si s no es vacía y todos sus caracteres son dígitos Unicode base 10; es un subconjunto de .isnumeric.
s.isdecimal()

Devuelve True (verdadero) si s no es vacía y todos sus caracteres son dígitos Unicode base 10 consecutivos; es un subconjunto de .isdigit.

s.isprintable() Devuelve True (verdadero) si s es vacía, o si todos sus caracteres son imprimibles, incluido el espacio en blanco, pero no el salto de línea.
s.isspace()

Devuelve True (verdadero) si s no es vacía, y todos sus caracteres son espacios en blanco.

s.startswith(t [, inicio, fin])

Devuelve True (verdadero) si s (opcionalmente, la partición [inicio:fin] de s) comienza con la cadena t.

s.endswith(t [, inicio, fin]) Devuelve True (verdadero) si s (opcionalmente, la partición [inicio:fin] de s) termina con la cadena t.
In [5]:
cadena_alpha = "ABCdeFGH"
cadena_alnum = "ABCdef123"
print(cadena_alpha.isalpha(), cadena_alpha.isalnum())
print(cadena_alnum.isalpha(), cadena_alnum.isalnum())
True True
False True

In [6]:
cadena = "asdlkfj sodiflkj"
print(cadena.islower(), cadena.isupper(), cadena.istitle())
cadena = "AKJHD KJHBDIU"
print(cadena.islower(), cadena.isupper(), cadena.istitle())
cadena = "Aaskdjh Doiuelkr"
print(cadena.islower(), cadena.isupper(), cadena.istitle())
True False False
False True False
False False True

In [7]:
a = '2'
print(a, a.isnumeric(), a.isdigit(), a.isdecimal())
a = '0.2'
print(a, a.isnumeric(), a.isdigit(), a.isdecimal())
a = '\u0661\u0662\u0663\u0664'
print(a, a.isnumeric(), a.isdigit(), a.isdecimal())
a = '\u2155'
print(a, a.isnumeric(), a.isdigit(), a.isdecimal())
a = '\u00b9\u00b2\u00b3\u2074'
print(a, a.isnumeric(), a.isdigit(), a.isdecimal())
a = '\u4e00\u4e8c\u4e09\u56db'
print(a, a.isnumeric(), a.isdigit(), a.isdecimal())
2 True True True
0.2 False False False
١٢٣٤ True True True
⅕ True False False
¹²³⁴ True True False
一二三四 True False False

In [8]:
cadena = "    "
print(cadena.isprintable(), cadena.isspace())
cadena = "  \t  "
print(cadena.isprintable(), cadena.isspace())
cadena = "  \n  "
print(cadena.isprintable(), cadena.isspace())
True True
False True
False True

Hay además una serie de métodos que devuelven información de tipo estadístico sobre una cadena:

s.count(t [, inicio, fin]) Devuelve el número de veces que aparece la cadena t en s
(opcionalmente, en la partición [inicio:fin]
s.find(t [, inicio, fin]) Devuelve el índice de la primera aparición de la cadena t en s
(opcionalmente, en la partición [inicio:fin].
Si la cadena no aparece, devuelve -1.
s.rfind(t [, inicio, fin]) Devuelve el índice de la última aparición de la cadena t en s
(opcionalmente, en la partición [inicio:fin]
Si la cadena no aparece, devuelve -1.
s.index(t [, inicio, fin]) Devuelve el índice de la primera aparición de la cadena t en s
(opcionalmente, en la partición [inicio:fin].
Si la cadena no aparece, devuelve un error.
s.rindex(t [, inicio, fin]) Devuelve el índice de la última aparición de la cadena t en s
(opcionalmente, en la partición [inicio:fin]
Si la cadena no aparece, devuelve un error.
In [9]:
cadena = "esta es una cadena con varias repeticiones"
print(cadena.count("e"))
print(cadena.count("es"))
print(cadena.find("a"))
print(cadena.rfind("a"))
print(cadena.find("x"))
print(cadena.index("n"))
print(cadena.rindex("n"))
print(cadena.index("z"))
6
3
3
27
-1
9
39

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-9-16f5e03d6c8c> in <module>()
      7 print(cadena.index("n"))
      8 print(cadena.rindex("n"))
----> 9 print(cadena.index("z"))

ValueError: substring not found

Diccionarios

Los diccionarios son objetos de tipo mapa: colecciones no ordenadas de pares de la forma clave : valor.

A diferencia de las secuencias, que son ordenadas, los valores de los diccionarios no se acceden mediante un índice, sino a través de su clave. Los diccionarios en sí son mutables, pero como clave se puede usar solamente objetos de tipo inmutable, como números, cadenas de caracteres, o tuplas.

Los valores pueden ser objetos de cualquie tipo.

Una forma sencilla de definir un diccionario es poniendo entre llaves los pares clave : valor, separados por comas.

In [10]:
meses = {"enero" : 1, "febrero" : 2, "marzo" : 3, "abril" : 4, 
         "mayo" : 5, "junio" : 6, "julio": 7, "agosto" : 8, 
         "septiembre" : 9, "octubre" : 10, "noviembre" : 11, "diciembre" : 12}

meses["octubre"]
Out[10]:
10

También se puede crear un diccionario usando la función dict(), que admite varias sintaxis posibles, además de la ya vista:

In [11]:
d0 = {"marca" : "Microtek", "modelo" : "Master UltraLight"}
d1 = dict({"marca" : "Microtek", "modelo" : "Master UltraLight"})
d2 = dict(marca="Microtek", modelo="Master UltraLight")
d3 = dict([("marca", "Microtek"), ("modelo", "Master UltraLight")])
d4 = dict(zip(("marca", "modelo"), ("Microtek", "Master UltraLight")))

print(d0)
print(d1)
print(d2)
print(d3["marca"], d4["modelo"])
{'modelo': 'Master UltraLight', 'marca': 'Microtek'}
{'marca': 'Microtek', 'modelo': 'Master UltraLight'}
{'modelo': 'Master UltraLight', 'marca': 'Microtek'}
Microtek Master UltraLight

Ejemplo 7.1

Definir una función que, utilizando un diccionario, devuelva el nombre de nota de una clase de altura expresada numéricamente. Complementar con la función que convierte una altura en número de nota MIDI en un número de clase de altura.

In [12]:
def p_a_pc(pitch):
    '''convierte una altura en número de nota MIDI en un número de clase de altura'''
    pc = pitch % 12
    return pc

def midi_a_nombre(pitch):
    nombres = {0 : "do", 1 : "do#", 2 : "re", 3 : "mib",
               4 : "mi", 5 : "fa", 6 : "fa#", 7 : "sol",
               8 : "lab", 9 : "la", 10 : "sib", 11 : "si"}
    pc = p_a_pc(pitch)
    return nombres[pc]

print(midi_a_nombre(66))

alturas = [72, 62, 59, 56, 67, 70, 66, 57, 63, 76, 73, 65]
print([midi_a_nombre(i) for i in alturas])    
fa#
['do', 're', 'si', 'lab', 'sol', 'sib', 'fa#', 'la', 'mib', 'mi', 'do#', 'fa']

Métodos y operaciones con diccionarios

len(D) Devuelve la longitud del diccionario D.
D[k] Devuelve el valor de la clave k del diccionario D,
o un error si k no se encuentra en el diccionario.
D[k] = v Asigna el valor v a la clave k del diccionario D.
del D[k] Elimina el item k del diccionario D.
k in D Devuelve True si k es una clave de D.
D.keys() Devuelve todas las claves en el diccionario D.
D.values() Devuelve todos los valores en el diccionario D.
D.items() Devuelve tuples (clave, valor) por cada ítem en el diccionario D.
D.clear() Borra todos los ítem en el diccionario D.
D.copy() Devuelve una copia del diccionario D.
D1.update(D2) Fusiona todas las entradas de D2 en D1. Similar a
for (k, v) in D2.items(): D1[k] = v.
D.get(k [, default]) Similar a D[k], pero si k no se encuentra en el diccionario devuelve
el default (o None si no hay default) en vez de dar un error.
D.setdefault(k, [, default]) Similar a D.get(key, default), pero además asigna la clave k
al valor por default si no se encuentra en el diccionario.
D.popitem() Devuelve y elimina un par arbitrario (clave, valor).
D.pop(k [, default]) Si k se encuentra en el diccionario, devuelve D[k] y borra k.
De lo contrario, devuelve el default.
D.fromkeys(seq [, value]) Crea un nuevo diccionario con claves a partir de una secuencia seq
y con valores asignados a value.

Ejercicio 7.1

  1. Crear una función que reciba como argumentos una secuencia de intervalos y una altura inicial, y que devuelva una secuencia de alturas. Las alturas se expresan como número de nota MIDI, y los intervalos en cantidad de semitonos, con valores negativos para los intervalos descendentes.
  2. Crear otra función que reciba como argumentos una lista y un diccionario; la lista representa una secuencia interválica, y el diccionario sirve para transformar cada intervalo en una secuencia de dos intervalos.
  3. Usando ambas funciones, desarrollar el programa de modo de que reciba una lista de intervalos y un diccionario de transformación, y devuelva una lista de alturas.

Ejercicio 7.2

Intentar extender la función del punto 2. anterior, de modo de que pueda aplicar la transformación varias veces recursivamente; el número de veces se controlará con un tercer argumento.