Paso de datos mediante diccionario y solución para el problema de print con los hilos.
Python permite pasar parámetros por valor (Paso por valor: Se crea una copia local de la variable dentro de la función) y por referencia (se maneja directamente la variable, los cambios realizados dentro de la función le afectarán también fuera).
[…]
stack.append / stack.pop
queue.popleft
{‘a’,‘b’,‘c’}
{A:1,B:2}
t = 1,‘a’,33
>>> fruits = ['orange', 'apple', 'pear', 'banana', 'kiwi', 'apple', 'banana'] >>> fruits.count('apple') 2 >>> fruits.count('tangerine') 0 >>> fruits.index('banana') 3 >>> fruits.index('banana', 4) # Find next banana starting at position 4 6 >>> fruits.reverse() >>> fruits ['banana', 'apple', 'kiwi', 'banana', 'pear', 'apple', 'orange'] >>> fruits.append('grape') >>> fruits ['banana', 'apple', 'kiwi', 'banana', 'pear', 'apple', 'orange', 'grape'] >>> fruits.sort() >>> fruits ['apple', 'apple', 'banana', 'banana', 'grape', 'kiwi', 'orange', 'pear'] >>> fruits.pop() 'pear'
>>> stack = [3, 4, 5] >>> stack.append(6) >>> stack.append(7) >>> stack [3, 4, 5, 6, 7] >>> stack.pop() 7 >>> stack [3, 4, 5, 6] >>> stack.pop() 6 >>> stack.pop() 5 >>> stack [3, 4]
>>> from collections import deque >>> queue = deque(["Eric", "John", "Michael"]) >>> queue.append("Terry") # Terry arrives >>> queue.append("Graham") # Graham arrives >>> queue.popleft() # The first to arrive now leaves 'Eric' >>> queue.popleft() # The second to arrive now leaves 'John' >>> queue # Remaining queue in order of arrival deque(['Michael', 'Terry', 'Graham'])
>>> basket = {'apple', 'orange', 'apple', 'pear', 'orange', 'banana'} >>> print(basket) # show that duplicates have been removed {'orange', 'banana', 'pear', 'apple'} >>> 'orange' in basket # fast membership testing True >>> 'crabgrass' in basket False >>> # Demonstrate set operations on unique letters from two words >>> a = set('abracadabra') >>> b = set('alacazam') >>> a # unique letters in a {'a', 'r', 'b', 'c', 'd'} >>> a - b # letters in a but not in b {'r', 'd', 'b'} >>> a | b # letters in a or b or both {'a', 'c', 'r', 'd', 'b', 'm', 'z', 'l'} >>> a & b # letters in both a and b {'a', 'c'} >>> a ^ b # letters in a or b but not both {'r', 'd', 'b', 'm', 'z', 'l'}
>>> tel = {'jack': 4098, 'sape': 4139} >>> tel['guido'] = 4127 >>> tel {'jack': 4098, 'sape': 4139, 'guido': 4127} >>> tel['jack'] 4098 >>> del tel['sape'] >>> tel['irv'] = 4127 >>> tel {'jack': 4098, 'guido': 4127, 'irv': 4127} >>> list(tel) ['jack', 'guido', 'irv'] >>> sorted(tel) ['guido', 'irv', 'jack'] >>> 'guido' in tel True >>> 'jack' not in tel False
>>> dict([('sape', 4139), ('guido', 4127), ('jack', 4098)]) {'sape': 4139, 'guido': 4127, 'jack': 4098} >>> dict(sape=4139, guido=4127, jack=4098) {'sape': 4139, 'guido': 4127, 'jack': 4098}
>>> t = 12345, 54321, 'hello!' >>> t[0] 12345 >>> t (12345, 54321, 'hello!') >>> # Tuplas unidas: >>> u = t, (1, 2, 3, 4, 5) >>> u ((12345, 54321, 'hello!'), (1, 2, 3, 4, 5)) >>> # Tuplas son inmutables NO se pueden cambiar t[0] = 88888 Traceback (most recent call last): File "", line 1, in TypeError: 'tuple' object does not support item assignment >>> # but they can contain mutable objects: >>> v = ([1, 2, 3], [3, 2, 1]) >>> v ([1, 2, 3], [3, 2, 1])
>>> empty = () >>> singleton = 'hello', # <-- note trailing comma >>> len(empty) 0 >>> len(singleton) 1 >>> singleton ('hello',)
valor | referencia |
---|---|
def doblar_valor(numero): numero *= 2 n = 10 doblar_valor(n) print(n) |
def doblar_valores(numeros): for i,n in enumerate(numeros): numeros[i] *= 2 ns = [10,50,100] doblar_valores(ns) print(ns) |
10 | [20, 100, 200] |
return | Una copia al vuelo de una lista con [:] |
def doblar_valor(numero): return numero * 2 n = 10 n = doblar_valor(n) print(n) |
def doblar_valores(numeros): for i,n in enumerate(numeros): numeros[i] *= 2 ns = [10,50,100] doblar_valores(ns[:]) print(ns) |
20 | [10, 50, 100] |
Cuando se pasan objetos como parámetros, las dos variables hacen referencia al mismo objeto. Eso significa que si el objeto pasado es mutable, cualquier modificación que la función invocada realice sobre su parámetro se reflejará en el argumento de la función llamadora:
referencia | valor |
---|---|
def modif(lista): lista[0]=5 def llama(): ls = [1,2,3,4] print ls modif(ls) print ls |
def cambia_ref(lista): lista=[5,1,2,3,4] def llama2(): ls=[1,2,3,4] print ls cambia_ref(ls) print ls |
>>> llama() [1, 2, 3, 4] [5, 2, 3, 4] |
>>> llama2() [1, 2, 3, 4] [1, 2, 3, 4] |
Una forma muy útil de saber lo que pasa por debajo de Python, es haciendo uso de la función id()
. Esta función nos devuelve un identificador único para cada objeto. Volviendo al primer ejemplo podemos ver como los objetos a los que “apuntan” x
y entrada
son distintos.
referencia | valor |
---|---|
x = 10 print(id(x)) # 4349704528 def funcion(entrada): entrada = 0 print(id(entrada)) # 4349704208 funcion(x) |
x = [10, 20, 30] print(id(x)) # 4422423560 def funcion(entrada): entrada.append(40) print(id(entrada)) # 4422423560 funcion(x) |
Los id son distintos | Los id son los mismos |
Nota: En Python el operador == sirve para comaparar el valor de dos variables y será true si es el mismo valor. El operdor is será true sí es la misma variable
>>> d1 = {"k1" : 1} >>> d2 = {"k1" : 1} >>> d1 == d2 True >>> d1 is d2 False
El operador is nos sirve pues para comparar referencias.
Definir una función con un número variable de argumentos.
Vamos a suponer que queremos una función que sume un conjunto de números, pero no sabemos a priori la cantidad de números que se quieren sumar. Si por ejemplo tuviéramos tres, la función sería tan sencilla como la siguiente.
def suma(a, b, c):
return a+b+c
suma(2, 4, 6)
#Salida: 12
def suma(*args): # *args es arbitrario puedes llamarlo *misparametros o lo que quieras es una simple tupla
s = 0
for arg in args:
s += arg
return s
# podemos mejrar el código poniendo directamente return sum(args)
suma(1, 3, 4, 2)
#Salida 10
suma(1, 1)
#Salida 2
En este caso, en vez de tener una tupla tenemos un diccionario. Puedes verificarlo de la siguiente forma con type().
def suma(**kwargs):
print(type(kwargs))
suma(x=3)
#<class 'dict'>
def suma(**kwargs):
s = 0
for key, value in kwargs.items():
print(key, "=", value)
s += value
return s
suma(a=3, b=10, c=3)
#Salida
#a = 3
#b = 10
#c = 3
#16
Lo único que necesitas saber es que debes definir la función en el siguiente orden:
def funcion(a, b, *args, **kwargs):
print("a =", a)
print("b =", b)
for arg in args:
print("args =", arg)
for key, value in kwargs.items():
print(key, "=", value)
funcion(10, 20, 1, 2, 3, 4, x="Hola", y="Que", z="Tal")
#Salida
#a = 10
#b = 20
#args = 1
#args = 2
#args = 3
#args = 4
#x = Hola
#y = Que
#z = Tal
def funcion(a, b, *args, **kwargs):
print("a =", a)
print("b =", b)
for arg in args:
print("args =", arg)
for key, value in kwargs.items():
print(key, "=", value)
args = [1, 2, 3, 4]
kwargs = {'x':"Hola", 'y':"Que", 'z':"Tal"}
funcion(10, 20, *args, **kwargs)
#Salida
#a = 10
#b = 20
#args = 1
#args = 2
#args = 3
#args = 4
#x = Hola
#y = Que
#z = Tal