<jupyter_start><jupyter_text>En la sección anterior, comenzamos a mirar la semántica de las variables y objetos de Python; aquí profundizaremos en la semántica de los distintos operadores incluidos en el lenguaje. Al final de esta sección, tendrá las herramientas básicas para comenzar a comparar y operar con datos en Python.Operaciones aritmeticasPython implementa siete operadores aritméticos binarios básicos, dos de los cuales pueden funcionar como operadores unarios. Se resumen en la siguiente tabla: ![tablaoperaciones.PNG](attachment:tablaoperaciones.PNG) Estos operadores se pueden utilizar y combinar de forma intuitiva, utilizando paréntesis estándar para agrupar operaciones. Por ejemplo:<jupyter_code># addition, subtraction, multiplication
(4 + 8) * (6.5 - 3)<jupyter_output><empty_output><jupyter_text>La división de piso es una división verdadera con partes fraccionarias truncadas:<jupyter_code># True division
print(11 / 2)
# Floor division
print(11 // 2)<jupyter_output>5<jupyter_text>El operador de división entera se agregó en Python 3; Si trabaja en Python 2, debe tener en cuenta que el operador de división estándar (/) actúa como división de piso para enteros y como división verdadera para números de punto flotante.Finalmente, mencionaré un octavo operador aritmético que se agregó en Python 3.5: el operador a @ b, que está destinado a indicar el producto matricial de a y b, para su uso en varios paquetes de álgebra lineal.  Operaciones bit a bitAdemás de las operaciones numéricas estándar, Python incluye operadores para realizar operaciones lógicas bit a bit en enteros. Se utilizan con mucha menos frecuencia que las operaciones aritméticas estándar, pero es útil saber que existen. Los seis operadores bit a bit se resumen en la siguiente tabla: ![tabla%20elementwise.PNG](attachment:tabla%20elementwise.PNG) Estos operadores bit a bit solo tienen sentido en términos de la representación binaria de números, que puede ver usando la función bin incorporada:<jupyter_code>bin(10)<jupyter_output><empty_output><jupyter_text>El resultado tiene el prefijo '0b', que indica una representación binaria. El resto de los dígitos indica que el número 10 se expresa como la suma 1⋅2^3 + 0⋅2^2 + 1⋅2^1 + 0⋅2^0. Del mismo modo, podemos escribir: Ahora, usando OR bit a bit, podemos encontrar el número que combina los bits de 4 y 10:<jupyter_code>4 | 10
bin(4 | 10)<jupyter_output><empty_output><jupyter_text>Estos operadores bit a bit no son inmediatamente útiles como los operadores aritméticos estándar, pero son útiles para verlos al menos una vez para comprender qué clase de operación realizan. En particular, los usuarios de otros idiomas a veces se sienten tentados a usar XOR (es decir, a ^ b) cuando realmente se refieren a exponenciación (es decir, a ** b).  Operaciones de asignaciónHemos visto que las variables pueden asignarse con el operador "=" y los valores almacenados para su uso posterior. Por ejemplo:<jupyter_code>a = 24
print(a)<jupyter_output>24<jupyter_text>Podemos usar estas variables en expresiones con cualquiera de los operadores mencionados anteriormente. Por ejemplo, para sumar 2 a a escribimos:<jupyter_code>a + 2<jupyter_output><empty_output><jupyter_text>Es posible que deseemos actualizar la variable con este nuevo valor; en este caso, podríamos combinar la suma y la asignación y escribir a = a + 2. Debido a que este tipo de operación y asignación combinadas es tan común, Python incluye operadores de actualización integrados para todas las operaciones aritméticas:<jupyter_code>a += 2  # equivalent to a = a + 2
print(a)<jupyter_output>26<jupyter_text>Hay un operador de asignación aumentado correspondiente a cada uno de los operadores binarios enumerados anteriormente; en resumen, son: ![orandxor.PNG](attachment:orandxor.PNG) Cada uno equivale a la operación correspondiente seguida de asignación: es decir, para cualquier operador "■", la expresión a ■ = b equivale a a = a ■ b, con una ligera captura. Para objetos mutables como listas, matrices o DataFrames, estas operaciones de asignación aumentada son en realidad sutilmente diferentes de sus contrapartes más detalladas: modifican el contenido del objeto original en lugar de crear un nuevo objeto para almacenar el resultado.  Operaciones de comparaciónOtro tipo de operación que puede resultar de gran utilidad es la comparación de diferentes valores. Para ello, Python implementa operadores de comparación estándar, que devuelven valores booleanos True y False. Las operaciones de comparación se enumeran en la siguiente tabla: ![Comparison%20Operations.PNG](attachment:Comparison%20Operations.PNG) Estos operadores de comparación se pueden combinar con los operadores aritméticos y bit a bit para expresar un rango virtualmente ilimitado de pruebas para los números. Por ejemplo, podemos comprobar si un número es impar comprobando que el módulo con 2 devuelve 1:<jupyter_code># 25 is odd
25 % 2 == 1
# 66 is odd
66 % 2 == 1<jupyter_output><empty_output><jupyter_text>Podemos unir varias comparaciones para verificar relaciones más complicadas:<jupyter_code># check if a is between 15 and 30
a = 25
15 < a < 30<jupyter_output><empty_output><jupyter_text>Y, solo para que te duela un poco la cabeza, echa un vistazo a esta comparación:<jupyter_code>-1 == ~0<jupyter_output><empty_output><jupyter_text>Recuerde que ~ es el operador de cambio de bits y, evidentemente, cuando cambia todos los bits de cero, termina con -1. Si tiene curiosidad por saber por qué es así, busque el esquema de codificación de enteros complementarios a dos, que es lo que Python usa para codificar enteros con signo, y piense en lo que sucede cuando comienza a voltear todos los bits de enteros codificados de esta manera.  Operaciones booleanasCuando se trabaja con valores booleanos, Python proporciona operadores para combinar los valores utilizando los conceptos estándar de "y", "o" y "no". Como era de esperar, estos operadores se expresan utilizando las palabras y, o, y no:<jupyter_code>x = 4
(x < 6) and (x > 2)
(x > 10) or (x % 2 == 0)
not (x < 6)<jupyter_output><empty_output><jupyter_text>Los aficionados al álgebra booleana pueden notar que el operador XOR no está incluido; esto, por supuesto, puede construirse de varias formas a partir de una declaración compuesta de los otros operadores. De lo contrario, un truco inteligente que puede usar para XOR de valores booleanos es el siguiente:<jupyter_code># (x> 1) xor (x <10) 
( x  >  1 )  != ( x  <  10 )<jupyter_output><empty_output><jupyter_text>Este tipo de operaciones booleanas serán extremadamente útiles cuando comencemos a discutir declaraciones de flujo de control como condicionales y bucles.Uno cosa confusa sobre el lenguaje es cuándo utilizar operadores booleanos ( and, or, not), y cuándo utilizar operaciones bit a bit ( &, |, ~). La respuesta está en sus nombres: los operadores booleanos deben usarse cuando desee calcular valores booleanos (es decir, verdad o falsedad) de declaraciones completas . Las operaciones bit a bit deben usarse cuando desee operar en bits individuales o componentes de los objetos en cuestión .  Operadores de identidad y membresía ¶Como and, or y not, Python también contiene operadores de prosa para verificar la identidad y la membresía. Son los siguientes: ![operadoresdeidentidad.PNG](attachment:operadoresdeidentidad.PNG)<jupyter_code>a  =  [ 1 ,  2 ,  3 ] 
b  =  [ 1 ,  2 ,  3 ]
a  ==  b
a  is  b<jupyter_output><empty_output><jupyter_text>¿Cómo se ven los objetos idénticos? Aquí hay un ejemplo:<jupyter_code>a  =  [ 1 ,  2 ,  3 ] 
b  =  a 
a  is  b<jupyter_output><empty_output><jupyter_text>La diferencia entre los dos casos aquí es que en el primero, a y b apunta a diferentes objetos , mientras que en el segundo  apuntan a la mismo objeto . Como vimos en la sección anterior, las variables de Python son punteros. El isoperador " " comprueba si las dos variables apuntan al mismo contenedor (objeto), en lugar de hacer referencia a lo que contiene el contenedor. Teniendo esto en cuenta, en la mayoría de los casos, un principiante se siente tentado a utilizar " is" lo que realmente quiere decir ==.  Operadores de membresía Los operadores de pertenencia comprueban la pertenencia a objetos compuestos. Entonces, por ejemplo, podemos escribir:<jupyter_code>1 in [1,2,3,4]
2 not in [1,2,3]<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.055568862275449105, 'fraction_numerical': 0.01437125748502994, 'mean_word_length': 5.399233716475096, 'pattern_counts': {'":': 0, '<': 64, '<?xml version=': 0, '>': 62, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '15', 'dir': 'jupyter-structured-clean-dedup', 'id': '607708', 'license': 'CNRI-Python', 'n_tokens_mistral': 2758, 'n_tokens_neox': 2682, 'n_words': 1136, 'path': '03-Basic Python Semantics Operators.ipynb', 'repo_name': 'JCRUNA/TourPorPython', 'size': '8350'}