¡Esta es una revisión vieja del documento!
Crean una lista a partir de otras.
Siguen el formato [variable_devuelta bucle(s) condicion(es)]:
>>> lst = [4, 6, 1, 8, 3, 0, 5, 9, 10, 7, 2] # Creación de la lista inicial >>> big = [n for n in lst if n > 5] # Selección de números mayores que 5 >>> big [6, 8, 9, 10, 7] >>> sbig = sorted([n for n in lst if n > 5]) # Y ordenados >>> sbig [6, 7, 8, 9, 10] >>> sbig = sorted(n for n in lst if n > 5) # Aunque entre paréntesis no es necesario poner los corchetes >>> sbig [6, 7, 8, 9, 10] >>> lst2 = [3, 5, 9] >>> [(n, n2) for n in lst for n2 in lst2 if n == n2] [(3, 3), (5, 5), (9, 9)] >>> [n for n in lst for n2 in lst2 if n == n2] [3, 5, 9] >>> listOfWords = ["this","is","a","list","of","words"] >>> [ word[0] for word in listOfWords ] ['t', 'i', 'a', 'l', 'o', 'w']
El siguiente crea pares de género (primero para news y luego para romance) y palabra en mayúsculas:
genre_word = [(genre, word.upper()) for genre in ['news', 'romance'] for word in words(categories=genre)]
Pueden ser combinadas con funciones del sistema como any o all:
myList = (2, 3, 5, 6) print any(x == 1 for x in myList) # False print any(x == 5 for x in myList) # True
También los diccionarios pueden ser creados así:
user_email = {user.name: user.email for user in users_list if user.email}
Esto crearía un objeto del estilo:
user_email = {'alfredgg': 'alfredgg@yahoo.es', 'diabolika': 'diabolikalau@gmail.com'}
O los sets:
users_first_names = {user.first_name for user in users}
Los generators son valores que se van generando on the fly, es decir, sólo puedes recoger un valor una vez ya que la lista no se guarda en memoria.
La sintaxis es la misma pero con paréntesis:
mygenerator = (x*x for x in range(3)) for i in mygenerator : print(i)
Los generadores no soportan el indexado (gen[3] daría error) ni el slicing (gen[:3] también daría error). Tampoco pueden concatenarse a las listas ni podremos realizar las funciones que hacemos con estas (consultar su tamaño, ordenarlo…).
Podemos realizar las siguientes acciones sobre ellos:
.next(), devuelve el siguiente valor.list(g), convertiría el generador en una lista.filtered_gen = (item for item in my_list if item > 3) filtered_gen.next() filtered_gen.next() filtered_gen.next()
Es una especie de return dentro de un bucle pero que conserva su valor para la próxima vez que se le invoque. Es decir, retorna un generator.
def func(l): while True: # Genera valores infinitos for v in l: yield v it = func([1, 9, 5, 6, 3]) it.next() # 1 it.next() # 9 it.next() # 5
with <inicialización> as <nombre de variable>: <bloque>. # Este código no libera file_handle si ocurre una excepción (MAL!): file_handle = open(path_to_file, 'r') for line in file_handle.readlines(): if raise_exception(line): print('No! An Exception!') # Código CORRECTO: with open(path_to_file, 'r') as file_handle: for line in file_handle: if raise_exception(line): print('No! An Exception!')
# sin reflection: Foo().hello() # con reflection: getattr(globals()['Foo'](), 'hello')()
getattr recoge un atributo por string de una clase, colección… dir devuelve en string los atributos y métodos de ese objeto.getmro de inspect devuelve la herencia de una clase.El siguiente ejemplo recoge las propiedades\métodos de un objeto y mira su herencia, si vienen de DataType realizará una acción con ellas.
def load (self, config): import inspect attrs = [getattr(self, prop) for prop in dir(self)] for attr in attrs: types = inspect.getmro(attr.__class__) if types[len(types)-1] == DataType: attr.load(config[attr.configname])
Una expresión lambda es una función sencilla de una sola línea. Son virtuales y no tienen un nombre con el que llamarlas. Se crean, se ejecutan y desaparecen, pero puedes guardarlas en una variable y llamarlas desde ella.
lambda <parametro1, parametro2…> : <línea de código devuelta>
a = lambda x,y : x*y a(3,4) # devolvería 12
(lambda x: x*2)(3) # devolvería 6
Realiza una llamada a una función para cada elemento del array:
lst = [1, 5, 8, 6, 4, 2, 3] map ((lambda x : x*3), lst) # retornaría: [3, 15, 24, 18, 12, 6, 9]
Retorna los elementos de una lista que al evaluarla con una función devuelven True:
lst = [1, 5, 8, 6, 4, 2, 3] filter((lambda x : x < 5), lst) # retornaría: [1, 4, 2, 3]
Ejecuta una función para cada elemento de un array acumulando su valor:
lst = [1, 5, 8, 6, 4, 2, 3] reduce((lambda x,y : x+y), lst) # retornaría: 29, la suma de todos los elementos de la colección
Función de comparación por longitud:
my_cmp = (lambda x,y: cmp(len(x), len(y))) my_cmp('abc', 'de')
Python trabaja internamente con objetos. Pocos son los datos que se guardan como valores y lo que comunmente denominamos “variables” serían mejor llamadas “nombres”. Y es que una asignación es un enlace de un nombre a un objeto.
>>> foo = Foo() >>> foo = 10 >>> print(foo.__add__) <method-wrapper '__add__' of int object at 0x8502c0>
Podríamos comprobar el string que devuelve una referencia con otra para saber si pertenecen al mismo objeto (ya que ese string representa la dirección de memoria en la que está almacenado). Aún así la forma de hacerlo correctamente es usando is.
is también es el comando indicado para comparar con None. Esto es porque None es un objeto singleton dentro del lenguaje.