"Las comprensiones de python proveen de una forma consisa de crear listas, diccionarios y conjuntos. Su nombre proviene de teria de conjuntos en donde la *notación contructiva de conjuntos* o comprensión se define como:\n",
"\n",
"\n",
"[Wikipedia](https://en.wikipedia.org/wiki/Set-builder_notation): Definir conjuntos por propiedades también se conoce como ***comprensión de conjuntos***, abstracción de conjuntos o como definición de la intención de un conjunto.\n",
"\n",
"En python la estructura de una comprensión es la siguiente:![img](https://python-3-patterns-idioms-test.readthedocs.io/en/latest/_images/listComprehensions.gif)"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[2, 2, 4, 6, 8]"
]
},
"execution_count": 1,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"old_list = [1,2,2,3,4,5,6,7,7,8,9]\n",
"new_list = []\n",
"for i in old_list:\n",
" if i%2==0:\n",
" new_list.append(i)\n",
"new_list"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[2, 2, 4, 6, 8]"
]
},
"execution_count": 2,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Lista\n",
"new_list=[i for i in old_list if i%2==0]\n",
"new_list"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"{0: 1,\n",
" 1: 1,\n",
" 2: 4,\n",
" 3: 27,\n",
" 4: 256,\n",
" 5: 3125,\n",
" 6: 46656,\n",
" 7: 823543,\n",
" 8: 16777216,\n",
" 9: 387420489}"
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Diccionario\n",
"{ i:i**i for i in range(10)}"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[[1, 0, 0], [0, 1, 0], [0, 0, 1]]"
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Comprensión anidada\n",
"k = [ [ 1 if item_idx == row_idx else 0 for item_idx in range(0, 3) ] for row_idx in range(0, 3) ]\n",
"k"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"{1, 2, 3, 4, 5, 6, 7, 8, 9}"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Conjunto\n",
"new_set={i for i in old_list}\n",
"new_set"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 2.2 Expresiones lambda $\\lambda$\n",
"Una función anónima o **expresión lambda** es una subrutina definida que no está enlazada a un identificador. Las funciones lambda generalmente son Argumentos que son pasados a otras funciónes de orden superior o Usadas para construir el resultado de una función de orden superior que necesita retornar una función [[Wikiedia](https://en.wikipedia.org/wiki/Anonymous_function)].\n",
"\n",
"En Python las expresiones lambda no pueden utilizar ciclos ni utilizar la plabra reservada **return**, su sintaxis es:```lambda <parametros>:<expresion>```\n",
"\n",
"*Nota: **filter** regresa una lista de elementos para los cuales una funcion regresa **True**; **map** aplica una funcion a todos los ementos de una lista.*\n",
"Los Generadores son funciones o expresiones que regesan un valor iterador en lugar de un valor, las para que una funcion regrese un generador en lugar de un valor se utiliza la palabra reservada **yield** en lugar de **return**."
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"0\n",
"1\n",
"2\n",
"3\n",
"4\n",
"5\n",
"15\n"
]
}
],
"source": [
"def firstn(n):\n",
" num = 0\n",
" while num < n:\n",
" yield num\n",
" print(num)\n",
" num += 1\n",
"\n",
"sum_of_first_n = sum(firstn(6))\n",
"print(sum_of_first_n)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Tambien es posible construir generadores utilizando expresiones utilizando parentesis en lugar de corchetes. Esto resulta util cuando utilizar una expresion generaria una lista muy grande que ocuparia mucha memoria."
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]\n",
"0\n",
"2\n",
"4\n",
"[6, 8, 10, 12, 14, 16, 18]\n"
]
}
],
"source": [
"doublesC = [2 * n for n in range(10)]\n",
"print(doublesC)\n",
"doublesG = (2 * n for n in range(10))\n",
"print(next(doublesG))\n",
"print(next(doublesG))\n",
"print(next(doublesG))\n",
"print(list(doublesG))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 2.4 Ejercicios\n",
"### 2.4.1\n",
"Dada una lista de enteros **a**, utilizando una comprensión, Imprimir una nueva lista que contenga \"par\" o \"impar\" en cada uno de sus elementos, dependiendo del valor del elemento en la lista orginal."
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[(0, 'par'),\n",
" (1, 'impar'),\n",
" (2, 'par'),\n",
" (3, 'impar'),\n",
" (4, 'par'),\n",
" (5, 'impar'),\n",
" (6, 'par'),\n",
" (7, 'impar'),\n",
" (8, 'par'),\n",
" (9, 'impar')]"
]
},
"execution_count": 12,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]\n",
"\n",
"def ParImpar(a):\n",
" '''La función imprime una nueva lista que contenga \"par\" o \"impar\" en cada uno de sus elementos, \n",
" dependiendo del valor del elemento en la lista orginal.\n",
" \n",
" Args:\n",
" a (list): Lista que contenga los enteros a evaluar\n",
" return [ (x, 'par') if x%2==0 else (x, 'impar') for x in a ]\n",
"\n",
"[ (x, 'par') if x%2==0 else (x, 'impar') for x in a ]\n",
"\n",
"\n",
"\n",
"ParImpar(a)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 2.4.2\n",
"Dada una lista *a*, utilizando una comprensión, imprimir una lista de tuplas, en donde cada tupla contiene el indice y el valor de elemento de la lista orginal."
"Utilizado ***reduce*** y una expresion *lambda*, obten la suma de todos lo elementos en una lista."
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"193"
]
},
"execution_count": 16,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"from functools import reduce\n",
"a = [5, 8, 10, 20, 50, 100]\n",
"\n",
"def sumaR(a):\n",
" '''\n",
" La función imprime una lista que contenga la suma de todos lo elementos en una lista,\n",
" Utilizado la funcion *reduce* y una expresion *lambda*. Los elementos de la lista deben ser enteros. \n",
" \n",
" Args:\n",
" a (list): Listas que contenga valores enteros que seran evaluados\n",
" \n",
" Ejemplo:\n",
" \n",
" >>> a = [5, 8, 10, 20, 50, 100]\n",
" >>> sumaR(a)\n",
" 193\n",
" \n",
" '''\n",
" from functools import reduce\n",
" return reduce(lambda n, m: n+m, a)\n",
"\n",
"sumaR(a)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 2.4.6 \n",
"Utilizando *map* y una expresion *lambda* obtener una lista cuyos elementos sean la suma de los elementos correspondientes en las listas **a** y **b**.\n"
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[35, 45, 55, 65]"
]
},
"execution_count": 17,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"a = [5, 10, 15, 20]\n",
"b = [30, 35, 40, 45]\n",
"\n",
"def sumaListas(a, b):\n",
" '''\n",
" La función imprime obtener una lista cuyos elementos sean la suma de los elementos \n",
" correspondientes en las listas *a* y *b* respectivamente, utilizando *map* y una expresion *lambda*\n",
" Los elementos de ambas listas deben ser enteros. \n",
" \n",
" Args:\n",
" a, b (list): Listas que contenga valores enteros que seran evaluados\n",
" \n",
" Ejemplo:\n",
" >>> a = [5, 10, 15, 20] \n",
" >>> b = [30, 35, 40, 45]\n",
" >>> sumaListas(a, b)\n",
" [35, 45, 55, 65]\n",
" \n",
" '''\n",
" return list( map( (lambda x, y: x+y), a, b ) )\n",
" \n",
"sumaListas(a, b)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 2.6.7\n",
"Escribir un generador en forma de expresion que obtenga las primeras 10 ternas pitagoricas.\n",
"\n",
"[Wikipedia](https://es.wikipedia.org/wiki/Terna_pitag%C3%B3rica): Una terna pitagórica es un conjunto ordenado de tres números enteros positivos a, b, c, y son solución de la ecuación diofantina cuadrática $a^{2}+b^{2}=c^{2}$.\n"
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[[(3, 4, 5),\n",
" (5, 12, 13),\n",
" (6, 8, 10),\n",
" (7, 24, 25),\n",
" (8, 15, 17),\n",
" (9, 12, 15),\n",
" (9, 40, 41),\n",
" (10, 24, 26),\n",
" (12, 16, 20),\n",
" (12, 35, 37)]]"
]
},
"execution_count": 18,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"def Terna(n):\n",
" ''' Generador en forma de expresion que obtiene las primeras n ternas pitagoricas\n",
" \n",
" Args:\n",
" n (int): Numero de Ternas Pitagoricas que serán regresadas por el generador\n",
" \n",
" Yields:\n",
" (object): Entrega un objeto que contiene todas las Ternas Pitagóricas hasta n, para visualizar\n",
" el objeto en forma de lista, es necesario utilizar la función list(Terna(n)).\n",
" yield from list( Permuta(string[:i]+string[i+1:], prefix+string[i]) )\n",
"\n",
" \n",
"list(Permuta(a))"
]
},
{
"cell_type": "code",
"execution_count": 20,
"metadata": {},
"outputs": [],
"source": [
"#no tomar en cuenta, es una prueba, el ejercicio final esta arriba\n",
"def permuta (vec,k,storage):\n",
" if k < len(vec):\n",
" for i in range(k,len(vec)):\n",
" vec[k], vec[i] = vec[i], vec[k]\n",
" permuta (vec, k+1, storage)\n",
" vec[k], vec[i] = vec[i], vec[k]\n",
" else:\n",
" storage.append(vec)\n",
" print(vec)\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 2.5 Modulos y Paquetes\n",
"En Python, cada uno de nuestros archivos .py se denominan módulos. Estos módulos, a la vez, pueden formar parte de paquetes. Un paquete, es una carpeta que contiene archivos .py. Para que una carpeta pueda ser considerada un paquete, debe contener un archivo de inicio llamado ``__init__.py``. Este archivo, no necesita contener ninguna instrucción. De hecho, puede estar vacío.\n",
"Python **Docstring** es el texto de documentación que puede aprecer en la definición de una clase, módulo, función o método, y se escribe como la primera declaración. Se puede acceder a las cadenas de documenacion desde el atributo doc para cualquiera de los objetos de Python y también con la función incorporada **help()**."
]
},
{
"cell_type": "code",
"execution_count": 22,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"function"
]
},
"execution_count": 22,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"def example_generator(n):\n",
" \"\"\"Generators have a ``Yields`` section instead of a ``Returns`` section.\n",
"\n",
" Args:\n",
" n (int): The upper limit of the range to generate, from 0 to `n` - 1.\n",
"\n",
" Yields:\n",
" int: The next number in the range of 0 to `n` - 1.\n",
"\n",
" Examples:\n",
" Examples should be written in doctest format, and should illustrate how\n",
" to use the function.\n",
"\n",
" >>> print([i for i in example_generator(4)])\n",
" [0, 1, 2, 3]\n",
"\n",
" \"\"\"\n",
" for i in range(n):\n",
" yield i\n",
"\n",
"type(example_generator)\n",
"#print(example_generator.__doc__)\n",
"#help(example_generator)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 2.6.1 pydoc\n",
"En la linea de comando el modulo **pydoc** permite general la documentacion de los modulo en formato html:\n"
]
},
{
"cell_type": "code",
"execution_count": 23,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"no Python documentation found for 'helloWorld.py'\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"bash: line 1: cd: miModulo: No such file or directory\n"
]
}
],
"source": [
"%%bash\n",
"cd miModulo\n",
"pydoc -w helloWorld.py"
]
},
{
"cell_type": "code",
"execution_count": 24,
"metadata": {},
"outputs": [],
"source": [
"#from IPython.display import HTML\n",
"#HTML(filename=\"miModulo/helloWorld.html\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 2.7 Casos de Prueba (doctest)\n",
"\n",
"doctest prueba el código fuente ejecutando ejemplos incrustados en la documentación y verificando que producen los resultados esperados. Funciona al analizar el texto de ayuda para encontrar ejemplos, ejecutarlos y luego comparar el texto de salida con el valor esperado.\n"
]
},
{
"cell_type": "code",
"execution_count": 25,
"metadata": {},
"outputs": [],
"source": [
"def multiply(a, b):\n",
" '''\n",
" >>> multiply(4, 3)\n",
" 12\n",
" >>> multiply('a', 3)\n",
" 'aaa'\n",
" '''\n",
" return a * b"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 2.8 Ejercicios\n",
"Escribe la documentacion y los casos de prueba para todos los ejercicios de la semana 1 y 2."
]
},
{
"cell_type": "code",
"execution_count": 26,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Help on function ParImpar in module __main__:\n",
"\n",
"ParImpar(a)\n",
" La función imprime una nueva lista que contenga \"par\" o \"impar\" en cada uno de sus elementos, \n",
" dependiendo del valor del elemento en la lista orginal.\n",
" \n",
" Args:\n",
" a (list): Lista que contenga los enteros a evaluar\n",