Mostrando entradas con la etiqueta listas. Mostrar todas las entradas
Mostrando entradas con la etiqueta listas. Mostrar todas las entradas

lunes, 6 de febrero de 2012

DICCIONARIOS PYTHON! [:-)]

**************************

Un diccionario es una estructura de datos que se caracteriza por realizar la indexación a sus datos por medio de una palabra o clave. En lugar de que el índice de la estructura sea un entero, en el diccionario la clave puede ser cualquier valor, un entero, un carácter o una palabra.

El formato típico de los diccionarios es el siguiente:

Diccionario = <clave, valor>

En donde la clave es el índice por el cual se accede al valor que le corresponde.

En Python se mantiene dicha nomenclatura para lo que son los diccionarios. En el siguiente ejemplo se puede observar como crear un diccionario en Python.

>>> dictPersona = {}
>>> dictPersona["nombre"] = "Pedro"
>>> dictPersona["apellido"] = "Andrade"
>>> dictPersona["dni"] = 31914936
>>> print dictPersona
{'nombre': 'Pedro', 'dni': 31914936, 'apellido': 'Andrade'}
>>> print dictPersona["nombre"]
Pedro

Los diccionarios son una estructura de datos fundamental cuando se quiere trabajar con Bases de Datos, ya que la mayoría de los ORM (Modelo Objeto-Relacional), utilizan listas de diccionarios para devolver el contenido de las consultas. Esto se debe a que la lista de diccionarios debe ser la forma mas cómoda y natural de representar una tabla, ya que los distintos elementos de la lista representarían cada uno de los reglones/registros y cada una de las tuplas Clave:Valor, reprensaría las columnas.

>>> tablaPersona = [{"nombre": "Jose", "apellido": "Thomas"},
...                 {"nombre": "Marcos", "apellido": "Aguirre"},
...                 {"nombre": "Rodolfo", "apellido": "Ricardi"}]


>>> for dict in tablaPersona:
...     print "-----------------------------"
...     for clave in dict.keys():
...             print str(clave) + "  =  " + str(dict[clave])
...     print "-----------------------------"
...


-----------------------------
nombre  =  Jose
apellido  =  Thomas
-----------------------------
-----------------------------
nombre  =  Marcos
apellido  =  Aguirre
-----------------------------
-----------------------------
nombre  =  Rodolfo
apellido  =  Ricardi
-----------------------------

El utilizar diccionarios nos da independencia de la posición física del dato dentro de la estructura.

Por ejemplo si tenemos el vector Persona y lo definimos de la siguiente manera:

>>> persona = ["Sebastian", "Schanz"]
>>> def mostrarPersonaVector(persona):
...     print "Nombre: " + persona[0]
...     print "Apellido: " + persona[1]
...
>>> mostrarPersonaVector(persona)
Nombre: Sebastian
Apellido: Schanz
>>> persona.insert(0,"31914934")
>>> mostrarPersonaVector(persona)
Nombre: 31914934
Apellido: Sebastian

Si tienes alguna consulta no dudes en dejar tu comentario que tratare de darte una mano a la mayor brevedad posible!...

Recorda que esto es una simple muestra de la potencia que tienen los diccionarios de Python y de cualquier lenguaje.

miércoles, 18 de enero de 2012

(ALGO INTERESANTE) - FUNCIONES COMO PARAMETROS

Quizás a esta altura ya hayan olvidado las funciones que habíamos creado en algún momento, en algún articulo de este BLOG. :). Por esta razón vamos a refrescar un poco su memoria y vamos a volver a escribirlas en la consola interactiva de Python.

>>> def sumar(num1, num2):
...     return num1+num2
...
>>> def mostrarMensaje(mensaje):
...     print mensaje
...
>>> def multiplicar(num1, num2):
...     return num1*num2
...
>>> mostrarMensaje("Otro dia")
Otro dia
>>> sumar(3,5)
8
>>> multiplicar(5,5)
25

Como se dijo previamente estas dos funciones van a ser accesibles solo desde esta sesión de consola.
Esto quiere decir que si cerramos y abrimos la consola interactiva de Python vamos a tener que volver a crear dichas funciones si deseamos utilizarlas.
De todas formas esto es suficiente para mostrar el ejemplo siguiente:

LISTA DE FUNCIONES

En Python las funciones son objetos de primer grado, esto quiere decir que se le pueden dar varios usos importantes, entre ellos se puede destacar que a las funciones se las puede pasar como parámetros o cargar dentro de una lista como si fueran variables, lo cual puede llegar a ser de muchísima ayuda. Esta funcionalidad  esta implementada muuuuuy sencillamente en Python a diferencia de otros lenguajes como por ejemplo C.

Veamos como se utiliza esto:

Antes de meternos de lleno en lo que son las listas de funciones, estaría bueno mostrarles como se hace en Python para pasar una función como parámetro. La realidad es que esto es muy simple.
Lo primero que hay que hacer es definir la funcion que va a recibir otra funcion por parametro.. :)
Luego internamente esa función se debería usar como se utilizaría normalmente.

>>> def operacion(funcion, operando1, operando2):
...     result = funcion(operando1,operando2)
...     return result
...
>>> operacion(multiplicar, 5,5)
25
>>> operacion(sumar,5,5)
10

Cabe aclarar que hay que tener cuidado con estos temas ya que pueden provocar muchos problemas en tiempo de ejecución. Por ejemplo si los tipos de los parámetros no concuerdan con los que debería recibir la función o si la cantidad de parámetros tampoco es la correcta, se producirán errores como se muestra a continuación.

>>> operacion(sumar,'a','b')
'ab'
>>> operacion(multiplicar,'b',7)
'bbbbbbb'

Como se explico anteriormente las cadenas pueden concatenarse utilizando el operador '+', y también puede multiplicarse una cadena por un entero X, lo cual genera la repeticion de la cadena X cantidad de veces.
En el ejemplo el carácter 'b' se multiplica por 7, lo que genera 'bbbbbbb'.
Lo que daría un error seria tratar de multiplicar dos cadenas.

>>> operacion(multiplicar,'a','b')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 2, in operacion
  File "<stdin>", line 2, in multiplicar
TypeError: can't multiply sequence by non-int of type 'str'

Así como también tratar de llamar a la función mostrarMensaje con más de un parámetro.

>>> operacion(mostrarMensaje,'Hola','Mundo')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 2, in operacion
TypeError: mostrarMensaje() takes exactly 1 argument (2 given)

Una lista de funciones se define de la misma manera que una lista de enteros, o una lista de cadenas.

Veamos un ejemplo.

Supongamos que deseamos aplicarle un conjunto de funciones a dos enteros en particular, para esto lo que hacemos es meter en una lista las funciones que deseamos aplicar y luego creamos un método que reciba esta lista de funciones y los enteros a los que le tenemos que aplicar las operaciones.

>>> # Se crea la lista de funciones
>>> listaFunciones = [sumar,multiplicar]
>>>
>>> # Se crea la funcion que recibe dicha lista y los enteros.
>>> def aplicarFunciones(lfunc,num1,num2):
...     for f in lfunc:
...             result = f(num1,num2)
...             print result
...
>>> # Llamamos a la funcion que aplicara cada una de las operaciones a ambos enteros.
>>> aplicarFunciones(listaFunciones,5,5)
10
25

Como puede observarse esto es muuuy potente, el hecho de poder modificar el comportamiento en tiempo de ejecución de una función en particular, nos da muchísima versatilidad para escribir código. Es cierto  que si se abusa de estas técnicas el código puedo volverse difícil de mantener y de seguir, pero los beneficios que conlleva la utilización de esta técnica, muchas veces puede superar ampliamente las problemáticas.

(MANEJO DE LISTAS)

Una de las cosas que más me atrajo de Python es la simplicidad con la que maneja las listas. Python brinda muchisimas facilidades que hacen que trabajar con listas no sea una tarea compleja.

Vamos a divertirnos un rato.. :)

NOTA: El primer elemento de la lista se encuentra en la posicion 0.



Creemos una lista con 5 elementos ordenados aleatoriamente:

>>> lista = [1,4,3,5,2]
>>> lista
[1, 4, 3, 5, 2]
>>> lista[0]
1

Si por ejemplo quisieramos tomar solo los elementos que se encuentran en la posicion 2 y 3 , es decir tomar una revanada de la lista, lo unico que deberiamos hacer seria lo siguiente:

>>> revanada = lista[2:4]
>>> revanada
[3, 5]

NOTA: Observar que se toman los elementos que se encuentran en el intervalo [2:4) es decir que no se toma el elemento que se encuentra en la posicion 4.

Si queremos tomar una revenada de la lista desde una posicion especifica hasta el final de la lista, hay que escribir lo siguiente:

>>> revanada = lista[2:]
>>> revanada
[3, 5, 2]

Como puede verse, se esta dejando abierto el final del intervalo mediante la expresión lista[2:]. De esta misma manera para tomar una revanada desde el principio de la lista hasta una posicion especifica, lo unico que habria que hacer es dejar abierto el intervalo pero de esta forma lista[:4].

>>> revanada = lista[:4]
>>> revanada
[1, 4, 3, 5]

Si haz pasado por otros lenguajes sabras que en la mayoria de ellos ordenar listas suele ser bastante tedioso, sin embargo Python trae un metodo de ordenamiento incorporado denominado sort. Podes probarlo haciendo lo siguiente:

>>> lista.sort()
>>> lista
[1, 2, 3, 4, 5]

Si te hiciera falta dar vuelta una lista, es decir que el primer elemento pase a ser el ultimo y que el ultimo pase a ser el primero, existe un método en Python que hace este trabajo por nosotros.

>>> lista = [1,2,3,4,5]
>>> lista
[1, 2, 3, 4, 5]
>>> lista.reverse()
>>> lista
[5, 4, 3, 2, 1]

NOTA: Tener en cuenta que el reverse es una operación "destructiva" ya que modifica el objeto sobre el cual se aplica la operación.

Se pueden ordenar listas heterogeneas como se muestra a continuación:

>>> listaHeterogenea = [2,1,'b','a']
>>> listaHeterogenea 
[2, 1, 'b', 'a']
>>> listaHeterogenea.sort()
>>> listaHeterogenea 
[1, 2, 'a', 'b']

Si tenes que contar la cantidad de apariciones de un elemento dentro de una lista, no te compliques que Python tiene una función que hace esto más fácil.

>>> lista = [1,2,3,2,2,5,3]
>>> lista.count(2)
3
>>> lista.count(3)
2
>>> lista.count(5)
1

Para agregar un elemento al final de una lista lo que hay que hacer es utilizar la función append() de listas y LISTO.. :)

>>> lista = [1,2,3,4]
>>> lista
[1, 2, 3, 4]
>>> lista.append(5)
>>> lista
[1, 2, 3, 4, 5]

Algo muy complejo es insertar un elemento en una posición específica de la lista, ya que hay que correr todos los elementos un espacio hacia adelante, para hacer un hueco en el cual pueda entrar el elemento que se desea insertar. Pero como esta es una función bastante común, Python cuenta con ella entre sus funciones integradas.
La función se llama insert y recibe la posición y el elemento en ese orden. Otro punto a favor.. :)

>>> lista = [1,2,3,4,5]
>>> lista.insert(0,0)
>>> lista
[0, 1, 2, 3, 4, 5]
>>> lista.insert(8,6)
>>> lista
[0, 1, 2, 3, 4, 5, 6]
>>> lista.insert(4,9)
>>> lista
[0, 1, 2, 3, 9, 4, 5, 6]

En el ejemplo puede observarse que se ingreso el elemento 0 (cero) en la posición 0 (cero) es decir al inicio de la lista. Luego se inserto el elemento 6 en la posición 8, como la lista tiene menos de 8 elementos se ingresa el elemento 6 al final de la lista. Y por ultimo se inserto el elemento 9 en la posición 4 de la lista. Todos los corrimientos se hacen automáticamente lo cual nos ahorra una gran cantidad de líneas de código.

Si lo que queremos saber es la posicion en la que aparece un elemento en la lista, debemos utilizar la funcion index() de listas.

>>> lista = [5,4,3,2,1]
>>> posicion = lista.index(5)
>>> posicion
0

Puede observarse que el numero 5 se encuentra en la posicion 0 (cero) de la lista.

NOTA: Hay que tener cuidado cuando se utiliza esta funcion ya que si se intenta realizar un index, con un elemento que no pertenece a la lista, se produce un error.

>>> posicion = lista.index(6)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: list.index(x): x not in list

Podría utilizarse en conjunto con la funcion "count()", ya que si se verifica que count es mayor que 0 (cero) es seguro que la funcion "index()" nos devolvera algo.
Cabe aclarar tambien que la funcion index() solo devolverá la posición de la primera aparición del elemento.

Para borrar un elemento de la lista se utiliza la función remove().

>>> lista = [5,4,3,2,1]
>>> lista
[5,4,3,2,1]
>>> lista.remove(2)
>>> lista
[5, 4, 3, 1]

Para concatenar dos o más listas hay dos formas sencillas, una es utilizando la función "extend()" y la otra utilizando el operador '+'.


Concatenacion con  extend()

>>> lista = [1,2,3]
>>> lista
[1, 2, 3]
>>> lista.extend([4,5])
>>> lista
[1, 2, 3, 4, 5]

con el operador '+'

>>> lista = [1,2,3]
>>> lista2 = [4,5]
>>> lista3 = lista + lista2
>>> lista3
[1, 2, 3, 4, 5]

NOTA: Al igual que con las cadenas con las listas también es valido utilizar el operador '*' (Multiplicación).

El resultado es el siguiente:

>>> lista = [1,2,3]
>>> lista2 = lista*2
>>> lista2
[1, 2, 3, 1, 2, 3]

Para tomar el mínimo y el máximo elemento de una lista, Python nos provee los métodos min() y max(), los cuales se utilizan de la siguiente manera:

>>> lista = [1,2,5,4,3]
>>> min(lista)
1
>>> max(lista)
5

Para saber el tamaño de una lista contamos con la funcion len(), la cual tambien puede aplicarse a cadenas y a otros tipos de datos que se veran más adelante.

>>> lista = [1,2,5,4,3]
>>> len(lista)
5

Para sumar los elementos de una lista Python nos provee una funcion llamada sum(), la cual recibe una lista de  numero y devuelve la suma de todos ellos.

>>> lista = [1,2,5,4,3]
>>> sum(lista)
15



Hay que tener cuidado al usar esta funcion ya que si la lista contiene elementos no numericos, la misma tirara un error como se muestra a continuacion.

>>> lista = [1,2,3,'a','b']
>>> sum(lista)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'int' and 'str'

Si se quiere obtener una lista sin repeticiones se puede utilizar el metodo set(), que nos retorna un conjunto con los elementos de la lista sin repeticiones.

>>> lista = [1,2,3,4,4,4,5,6,7,6]
>>> lista2 = set(lista)
>>> lista2
set([1, 2, 3, 4, 5, 6, 7])

NOTA: Hay que tener en cuenta que los conjuntos (set) no son indexsables por lo cual la ejecucion de lista2[1] nos dara el error que se muestra a continuacion.

>>> lista2[1]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'set' object does not support indexing

Para acceder uno a uno a los elementos del set, lo mejor es hacerlo por medio de un "for" ya que el set es una estructura iterable.. :P

Por ultimo y para terminar con listas, puedo comentarles que Python nos da la posibilidad de trabajar con las listas como si fueran una estructura de datos de tipo cola o de tipo pila, ya que nos brinda la funcion append() para ingresar elementos al final de la "lista" y también nos brinda la función pop() para ir tomando el ultimo elemento de la lista.
Hay que tener en cuenta que las estructuras de datos de tipo Pila son aquellas en las que el ultimo elemento en insertarse es el primero en sacarse, es por esta razón que se dice que son de tipo LIFO (Last In First Out), por lo cual una Pila en Python estaría dada por una lista que utilice los metodos append() para insertar elementos y pop() para quitarlos.

Lista como Pila

>>> lista = [1,2,3]
>>> lista
[1, 2, 3]
>>> lista.append(4)
>>> lista
[1, 2, 3, 4]
>>> lista.pop()
4
>>> lista
[1, 2, 3]
>>> lista.pop()
3
>>> lista
[1, 2]

Por otro lado una cola, que es una estructura de datos de tipo FIFO (First In First Out) debido a que los elementos se van tomando por orden de llegada, es una estructura igual de facil de implementar pero menos eficiente.
Python esta muy bien preparado para tomar el último elemento de una lista y para insertar un elemento al final de una lista. Pero pierde bastante performance al tomar el primer elemento de una lista y al insertar un elemento al principio de una lista.
De todas formas si se va trabajar con listas pequeñas, esto no es un problema.
Se puede simular una cola mediante una lista que utiliza el método append() para la inserción de elementos y el método pop(0) para tomar los elementos. O tambien utilizando la funcion insert() para insertar al principio de la lista y la funcion pop() para tomar los elementos del final. Esto puede quedar mas claro con el siguiente ejemplo:

>>> lista = [1,2,3]
>>> lista.append(4)
>>> lista
[1, 2, 3, 4]
>>> lista.pop(0)
1
>>> lista.pop(0)
2
>>> lista.append(5)
>>> lista
[3, 4, 5]

NOTA: En Python existe una forma más eficiente de trabajar con Colas, pero lo miraremos mas adelante. Si alguno quiere investigar por su cuenta le comento solamente que deben importar desde collections la clase deque

            from collections import deque