0% encontró este documento útil (0 votos)
4 vistas

TallerPython

Lenguaje Python

Cargado por

Martin Regini
Derechos de autor
© © All Rights Reserved
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
4 vistas

TallerPython

Lenguaje Python

Cargado por

Martin Regini
Derechos de autor
© © All Rights Reserved
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
Está en la página 1/ 18

TallerPython

November 22, 2018

Este PDF puede estar desactualizado. El notebook al día puede ser visto acá:
https://github.com/algoritmos-rw/algo2_apuntes/blob/master/TallerPython.ipynb

1 Un poco de Historia
• Python fue creado a finales de los años 80 por un programador holandés llamado Guido
van Rossum, quien sigue siendo aún hoy el líder del desarrollo del lenguaje.

• El nombre del lenguaje proviene de los humoristas británicos Monty Python.

"I chose Python as a working title for the project, being in a slightly irreverent mood (and a big
fan of Monty Python’s Flying Circus)."

2 Diferencias entre C y Python


Lenguaje de programación C: - Compilado - Tipado estático - Procedural - Bajo nivel - Permite
acceso a memoria de bajo nivel mediante punteros
Python: - Interpretado - Tipado dinamico - Multiparadigma - Alto nivel - Tiene un recolector
de basura (no hay malloc, free, realloc, etc)

3 La filosofía de Python
In [3]: import this

The Zen of Python, by Tim Peters

Beautiful is better than ugly.


Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.

1
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!

4 Conocimientos Básicos de Python


In [4]: '''Este es un comentario'''
print("Hello World!") # Este es un comentario en linea

Hello World!

In [5]: # Declaración de variables


string = 'Hola'
print(string)
entero = 1
print(entero)
flotante = 1.0
print(flotante)
tupla = (entero,flotante)
print(tupla)
nupla = (entero,flotante,string)
print(nupla)
lista = [entero,flotante,string]
print(lista)
diccionario = {'1':tupla,50:nupla,'3':entero}
print(diccionario)
conjunto = set([1,2])
print(conjunto)

Hola
1
1.0
(1, 1.0)
(1, 1.0, 'Hola')
[1, 1.0, 'Hola']
{'1': (1, 1.0), 50: (1, 1.0, 'Hola'), '3': 1}
{1, 2}

In [6]: # Pueden cambiar de tipo


elemento = 1

2
print(elemento)
print(type(elemento))
elemento = "uno"
print(elemento)
print(type(elemento))

1
<class 'int'>
uno
<class 'str'>

5 Funciones en Python
In [7]: # Definir una función
def suma(a,b):
return a+b

print(suma(1,2))
print(suma(1.0,2.0))
print(suma(1.0,2))
print(suma("hola ","como te va"))
print(suma([1,2,3],[4,5]))
print(suma("1",3)) # Falla

3
3.0
3.0
hola como te va
[1, 2, 3, 4, 5]

---------------------------------------------------------------------------

TypeError Traceback (most recent call last)

<ipython-input-7-193b5862090a> in <module>()
8 print(suma("hola ","como te va"))
9 print(suma([1,2,3],[4,5]))
---> 10 print(suma("1",3)) # Falla

<ipython-input-7-193b5862090a> in suma(a, b)
1 # Definir una función
2 def suma(a,b):
----> 3 return a+b
4

3
5 print(suma(1,2))

TypeError: must be str, not int

In [8]: # El valor por default de divisor es 1


def division(dividendo,divisor=1):
return dividendo/divisor

print(division(4)) # Usa el valor por default


print(division(1,2)) # Parámetros por orden
print(division(dividendo=1,divisor=2)) # Parámetros por nombre
print(division(divisor=2,dividendo=1))

4.0
0.5
0.5
0.5

6 Diferencia entre lista y tupla


Las listas se caracterizan por ser mutables, es decir, se puede cambiar su contenido en tiempo de
ejecución, mientras que las tuplas son inmutables ya que no es posible modificar el contenido una
vez creada.

7 Listas de Python
In [9]: # Como hacer una lista
lista = [] # A modo de ejemplo llamamos a la lista "lista", pero no deben llamar a las

# Como agregar cosas a la lista


lista.append(1) # Inserto un 1 al final
lista.append("dos") # Inserto un "dos" al final
lista.append(3.0) # Inserto un 3.0 al final
lista.insert(2,10) # Inserto en posicion 2 un 10
print(lista)

print(lista[2]) # Imprimo elemento en la posición 2


print(lista[-1]) # Imprimo elemento en la última posición
print(lista[10]) # Falla

[1, 'dos', 10, 3.0]


10
3.0

4
---------------------------------------------------------------------------

IndexError Traceback (most recent call last)

<ipython-input-9-98399ff64c8a> in <module>()
11 print(lista[2]) # Imprimo elemento en la posición 2
12 print(lista[-1]) # Imprimo elemento en la última posición
---> 13 print(lista[10]) # Falla

IndexError: list index out of range

In [10]: # Como iterar una lista elemento por elemento


print("Primera iteración")
for elemento in lista:
print ("\t",elemento)

print("Segunda iteración")
for i, elemento in enumerate(lista):
print("\tIndice:",i)
print("\tValor:",elemento)

# Como hacer un ciclo for que recorra la lista


print("Tercera iteración")
for i in range(0,2):
print("\t",lista[i])

# Como hacer un ciclo while que recorra la lista


print("Cuarta iteración")
i = 0
while i<len(lista):
print("\t",lista[i])
i+=1 # No se puede hacer i++ o ++i

# Como remover por elemento


lista.remove(1) # Elimina la primer aparición de 1
print(lista)

# Como remover por posicion


elemento = lista.pop(1) # Elimina el elemento en la posición pasada por parámetro
# si no se le pasa nada elimina el último
print(elemento)
print(lista)

Primera iteración
1

5
dos
10
3.0
Segunda iteración
Indice: 0
Valor: 1
Indice: 1
Valor: dos
Indice: 2
Valor: 10
Indice: 3
Valor: 3.0
Tercera iteración
1
dos
Cuarta iteración
1
dos
10
3.0
['dos', 10, 3.0]
10
['dos', 3.0]

8 Condicionales (if...elif...else)
if <condición_1>:
<hacer algo_1 si se da la condición_1>
elif <condición_2>:
<hacer algo_2 si se da la condición_2>
...
elif <condición_n>:
<hacer algo_n si se da la condición_n>
else:
<hacer otra cosa si no dan las anteriores>

In [11]: def busqueda_binaria(lista, elemento):


# not equivale a ! en C
# True y False empiezan con mayúscula
if not lista: return False
elif len(lista) == 1: # len(lista) devuelve el largo de la lista
return lista[0] == elemento
mitad = len(lista)//2 # // es la operación división entera
if lista[mitad] == elemento: return True
if lista[mitad]>elemento:
return busqueda_binaria(lista[:mitad],elemento)

6
if lista[mitad]<elemento:
return busqueda_binaria(lista[mitad:],elemento)

print(busqueda_binaria([1,2,3,4,5],4))
print(busqueda_binaria([1,4,6,7,9,10],2))

True
False

9 Slices
Valen para listas, tuplas o strings (segmentos)

In [12]: numeros = [1,2,3,4,5,6,7,8,9,10]


print(numeros[0:2])
print(numeros[-4:-2])
print(numeros[0:80])
print(numeros[:3])
print(numeros[3:])
print(numeros[::2])

numeros = numeros[::-1]
print(numeros)

[1, 2]
[7, 8]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
[1, 2, 3]
[4, 5, 6, 7, 8, 9, 10]
[1, 3, 5, 7, 9]
[10, 9, 8, 7, 6, 5, 4, 3, 2, 1]

10 Diccionarios de Python
Son como hashmaps, las claves deben ser inmutables para que no pierda sentido el diccionario. Si
se pudieran modificar, se podría cambiar las claves y podría generar conflictos.
Tipos mutables: - Listas - Diccionarios - Sets
Tipos inmutables: - Int - Float - String - Tuplas

In [13]: cad = "Hola"


cad[0]

Out[13]: 'H'

In [14]: # Cómo hacer un diccionario


diccionario = {}

7
# Cómo agregar cosas al diccionario
diccionario['clave1'] = 'valor1'
diccionario[2] = 'valor2'
diccionario['clave3'] = 3
print(diccionario)

# [('clave1','valor1'),('clave2','valor2'),('clave3',3)]
print(diccionario.get('clave3',2)) # Equivalente a diccionario['clave3']
# pero en caso de no tener la clave, devuelve
# un elemento por default (en este caso 2)

print ('clave1' in diccionario) # Verifico si la clave está en el diccionario

# Cómo iterar un diccionario elemento por elemento


print("Primera iteración")
for clave,valor in diccionario.items(): # diccionario.items() va devolviendo tuplas co
# con esta sintaxis se desempaquetan en clave
print("\tClave: " + str(clave))
print("\tValor: " + str(valor))

print("Segunda iteración: claves")


for clave in diccionario.keys():
print("\t"+str(clave))

print("Tercera iteración: valores")


for valor in diccionario.values():
print("\t"+str(valor))

{'clave1': 'valor1', 2: 'valor2', 'clave3': 3}


3
True
Primera iteración
Clave: clave1
Valor: valor1
Clave: 2
Valor: valor2
Clave: clave3
Valor: 3
Segunda iteración: claves
clave1
2
clave3
Tercera iteración: valores
valor1
valor2
3

8
11 Sets
Son similares a los diccionarios pero se almacenan solo claves, y tienen algunas operaciones par-
ticulares.

In [15]: help("set")

Help on class set in module builtins:

class set(object)
| set() -> new empty set object
| set(iterable) -> new set object
|
| Build an unordered collection of unique elements.
|
| Methods defined here:
|
| __and__(self, value, /)
| Return self&value.
|
| __contains__(...)
| x.__contains__(y) <==> y in x.
|
| __eq__(self, value, /)
| Return self==value.
|
| __ge__(self, value, /)
| Return self>=value.
|
| __getattribute__(self, name, /)
| Return getattr(self, name).
|
| __gt__(self, value, /)
| Return self>value.
|
| __iand__(self, value, /)
| Return self&=value.
|
| __init__(self, /, *args, **kwargs)
| Initialize self. See help(type(self)) for accurate signature.
|
| __ior__(self, value, /)
| Return self|=value.
|
| __isub__(self, value, /)
| Return self-=value.
|
| __iter__(self, /)

9
| Implement iter(self).
|
| __ixor__(self, value, /)
| Return selfˆ=value.
|
| __le__(self, value, /)
| Return self<=value.
|
| __len__(self, /)
| Return len(self).
|
| __lt__(self, value, /)
| Return self<value.
|
| __ne__(self, value, /)
| Return self!=value.
|
| __new__(*args, **kwargs) from builtins.type
| Create and return a new object. See help(type) for accurate signature.
|
| __or__(self, value, /)
| Return self|value.
|
| __rand__(self, value, /)
| Return value&self.
|
| __reduce__(...)
| Return state information for pickling.
|
| __repr__(self, /)
| Return repr(self).
|
| __ror__(self, value, /)
| Return value|self.
|
| __rsub__(self, value, /)
| Return value-self.
|
| __rxor__(self, value, /)
| Return valueˆself.
|
| __sizeof__(...)
| S.__sizeof__() -> size of S in memory, in bytes
|
| __sub__(self, value, /)
| Return self-value.
|
| __xor__(self, value, /)

10
| Return selfˆvalue.
|
| add(...)
| Add an element to a set.
|
| This has no effect if the element is already present.
|
| clear(...)
| Remove all elements from this set.
|
| copy(...)
| Return a shallow copy of a set.
|
| difference(...)
| Return the difference of two or more sets as a new set.
|
| (i.e. all elements that are in this set but not the others.)
|
| difference_update(...)
| Remove all elements of another set from this set.
|
| discard(...)
| Remove an element from a set if it is a member.
|
| If the element is not a member, do nothing.
|
| intersection(...)
| Return the intersection of two sets as a new set.
|
| (i.e. all elements that are in both sets.)
|
| intersection_update(...)
| Update a set with the intersection of itself and another.
|
| isdisjoint(...)
| Return True if two sets have a null intersection.
|
| issubset(...)
| Report whether another set contains this set.
|
| issuperset(...)
| Report whether this set contains another set.
|
| pop(...)
| Remove and return an arbitrary set element.
| Raises KeyError if the set is empty.
|
| remove(...)

11
| Remove an element from a set; it must be a member.
|
| If the element is not a member, raise a KeyError.
|
| symmetric_difference(...)
| Return the symmetric difference of two sets as a new set.
|
| (i.e. all elements that are in exactly one of the sets.)
|
| symmetric_difference_update(...)
| Update a set with the symmetric difference of itself and another.
|
| union(...)
| Return the union of sets as a new set.
|
| (i.e. all elements that are in either set.)
|
| update(...)
| Update a set with the union of itself and others.
|
| ----------------------------------------------------------------------
| Data and other attributes defined here:
|
| __hash__ = None

12 Lectura y escritura de archivos


In [16]: import random
with open('archivo.csv','w') as archivo: # Al usar esta sintaxis no es necesario hacer
archivo.write("Alumno, nota\n")
# Tambien de forma similar al fprintf se puede hacer:
# print("Alumno, nota\n", file=archivo)
for i in range(0,10):
archivo.write(str(i) + "," + str(random.randrange(0,10))+"\n")

print(archivo) # Comentario aclaratorio:


# Las variables definidas en un determinado scope siguen existiendo po
# Se debe tener cuidado con esto, ya que nada garantiza que por fuera

<_io.TextIOWrapper name='archivo.csv' mode='w' encoding='UTF-8'>

In [17]: with open('archivo.csv','r') as f:


for linea in f:
print(linea)
# print(linea, end="") # Reemplaza "\n" por ""

12
Alumno, nota

0,8

1,9

2,0

3,4

4,2

5,6

6,6

7,3

8,9

9,6

13 Archivos CSV
In [18]: import csv
with open('archivo.csv','r') as f:
f_reader = csv.DictReader(f,delimiter=',')
#f_reader = csv.reader(f,delimiter = ',') # Devuelve lista de elementos
for row in f_reader:
print(row)

OrderedDict([('Alumno', '0'), (' nota', '8')])


OrderedDict([('Alumno', '1'), (' nota', '9')])
OrderedDict([('Alumno', '2'), (' nota', '0')])
OrderedDict([('Alumno', '3'), (' nota', '4')])
OrderedDict([('Alumno', '4'), (' nota', '2')])
OrderedDict([('Alumno', '5'), (' nota', '6')])
OrderedDict([('Alumno', '6'), (' nota', '6')])
OrderedDict([('Alumno', '7'), (' nota', '3')])
OrderedDict([('Alumno', '8'), (' nota', '9')])
OrderedDict([('Alumno', '9'), (' nota', '6')])

In [19]: from csv import writer as writerPiola


with open('archivo.csv','w') as f:
f_writer = writerPiola(f,delimiter=',')

13
f_writer.writerow([1,2])
f_writer.writerow([2,3])
f_writer.writerow([4,5])

14 Split y Join
• Split: opera sobre un string, recibe un delimitador, y devuelve una lista de fragmentos del
string delimitados por el delimitador.
• Join: opera sobre un string (delimitador), recibe una lista de strings, y devuelve un string de
los fragmentos unidos por el delimitador.

In [20]: separadas = "hola, don, pepito".split(",")


print(separadas)
unidas = "".join(separadas)
print(unidas)

['hola', ' don', ' pepito']


hola don pepito

15 Objetos
Los objetos tiene metodos y atributos: - Atributos: equivalentes a variables. - Métodos: equiva-
lentes a las funciones.
Se puede trazar una equivalencia entre los objetos y los structs de C, "ambas son estructuras
en las que se le pueden guardar cosas".
La clase de un objeto es el tipo.
Por ejemplo:
En C, para definir un nodo haciamos:

typedef struct nodo {


void* dato;
struct nodo* siguiente;
} nodo_t;

16 Cómo creo una clase


In [21]: class Nodo (object):

def __init__(self,dato,siguiente = None):


self.dato = dato
self.siguiente = siguiente

def obtener_dato(self):
return self.dato;

def proximo(self):

14
return self.siguiente

def __repr__(self):
return str(self.dato)

def __str__(self):
return str(self.dato)

In [22]: nodo = Nodo("hola")


print(nodo)
nodo2 = Nodo("lala")
print([nodo,nodo2])
nodo3 = nodo.obtener_dato()
print(nodo3)

hola
[hola, lala]
hola

17 Ejemplo: Lista Enlazada


In [23]: class Lista_Enlazada(object):

def __init__(self):
self.primero = None
self.ultimo = None
self.largo = 0

def insertar_al_principio(self,dato):
nodo = Nodo(dato, self.primero)
self.primero = nodo
self.largo += 1
if self.largo == 1:
self.ultimo = nodo

def insertar_al_final(self,dato):
if self.largo != 0:
nodo = Nodo(dato)
nodo_anterior = self.ultimo
nodo_anterior.siguiente = nodo
self.ultimo = nodo
self.largo += 1
else:
self.insertar_al_principio(dato)

def ver_primero(self):
return self.primero.obtener_dato();

15
def borrar_primero(self):
dato = self.primero.obtener_dato()
self.primero = self.primero.siguiente
self.largo -= 1
if self.largo == 0:
self.ultimo = None
return dato

def __str__(self):
cadena = ""
nodo_actual = self.primero
while nodo_actual is not None:
cadena += str(nodo_actual.obtener_dato())
cadena += " | "
nodo_actual = nodo_actual.siguiente
return cadena

lista = Lista_Enlazada()
lista.insertar_al_principio("Primer Dato")
lista.insertar_al_principio("Primer primer Dato")
elemento = lista.ver_primero()
print(elemento)
print(str(lista))

Primer primer Dato


Primer primer Dato | Primer Dato |

18 Librería para Heaps


In [24]: import heapq

heap = [5,2,3,7,2,20,1]
heapq.heapify(heap)
print(heap)

heapq.heappush(heap,27)
print(heap)

menor = heapq.heappop(heap)
print(menor)
print(heap)

n_menores = heapq.nsmallest(3,heap)
print(n_menores)

16
[1, 2, 3, 7, 2, 20, 5]
[1, 2, 3, 7, 2, 20, 5, 27]
1
[2, 2, 3, 7, 27, 20, 5]
[2, 2, 3]

19 Y como hacer un Max-Heap


In [25]: class Nodo_heap(object):
def __init__(self,dato):
self.dato = dato

def obtener_valor():
return dato

def __lt__(self, other):


return self.dato>other.dato

def __gt__(self, other):


return self.dato<other.dato

def __eq__(self, other):


return self.dato==other.dato

def __str__(self):
return str(self.dato)

def __repr__(self):
return str(self.dato)

In [26]: heap = [Nodo_heap(5),Nodo_heap(2),Nodo_heap(3),Nodo_heap(7),Nodo_heap(2),Nodo_heap(20)


heapq.heapify(heap)
print(heap)

[20, 7, 5, 2, 2, 3, 1]

19.1 Concepto de Cola


El comportamiento de una cola se puede describir con la frase "Lo primero que se encoló es lo
primero que se usa". Es decir, su estructura es FIFO (First in, First out)
Suponiendo que implementamos una cola usando una lista. £Cómo se podría implementar?
£Cuál sería el costo?
Opción 1: * enqueue encola al principio de la lista * dequeue desencola del final de la lista
Opción 2: * enqueue encola al final de la lista * dequeue desencola del principio de la lista

17
Problema: En el primer caso encolar y en el segundo caso desencolar del principio implica
desplazar todo el contenido de la lista (en un sentido u otro). Esta operación es costosa, imaginense
una lista muy grande!

19.2 Deque como Cola


Deque: diseñado para appends y pops eficientes en ambos extremos

• Operación encolar: se usa la función append()


• Operacion dequeue (desencolar): se usa la función popleft()

In [27]: from collections import deque

queue = deque(["a", "b", "c"])


print(queue)
queue.append("d")
print(queue)
queue.popleft()
print(queue)
print(type(queue))

deque(['a', 'b', 'c'])


deque(['a', 'b', 'c', 'd'])
deque(['b', 'c', 'd'])
<class 'collections.deque'>

19.3 Recursos
• Apunte de Algoritmos y Programación I

• Automate the Boring Stuff with Python

• Curso Python

• Python Tutor

• Learn Python3 in Y minutes

• Bibliografía de Algoritmos y Programación I

18

También podría gustarte