list\(xrange\(\)\) == range\(\) --> In python3 range is the xrange of python2 \(it is not a list but a generator\)
The difference between a Tuple and a List is that the position of a value in a tuple gives it a meaning but the lists are just ordered values. Tuples have structures, lists have order
### Main operations
To raise a number you should do: 3\*\*2 \(it isn't 3^2\)
If you do 2/3 it returns 1 because you are dividing two ints. If you want decimals you should divide floats \(2.0/3.0\).
**zip** stops when the shorter of foo or bar stops:
```text
for f, b in zip(foo, bar):
print(f, b)
```
**Lambda** is used to define a function
\(lambda x,y: x+y\)\(5,3\) = 8 --> Use lambda as simple **function**
**sorted**\(range\(-5,6\), key=lambda x: x\*\* 2\) = \[0, -1, 1, -2, 2, -3, 3, -4, 4, -5, 5\] --> Use lambda to sort a list
m = **filter**\(lambda x: x % 3 == 0, \[1, 2, 3, 4, 5, 6, 7, 8, 9\]\) = \[3, 6, 9\] --> Use lambda to filter
**reduce** \(lambda x,y: x\*y, \[1,2,3,4\]\) = 24
```text
def make_adder(n):
return lambda x: x+n
plus3 = make_adder(3)
plus3(4) = 7 # 3 + 4 = 7
class Car:
crash = lambda self: print('Boom!')
my_car = Car(); my_car.crash() = 'Boom!'
```
mult1 = \[x for x in \[1, 2, 3, 4, 5, 6, 7, 8, 9\] if x%3 == 0 \]
### Exceptions
```text
def divide(x,y):
try:
result = x/y
except ZeroDivisionError, e:
print “division by zero!” + str(e)
except TypeError:
divide(int(x),int(y))
else:
print “result i”, result
finally
print “executing finally clause in any case”
```
### Assert\(\)
If the condition is false the string will by printed in the screen
```text
def avg(grades, weights):
assert not len(grades) == 0, 'no grades data'
assert len(grades) == 'wrong number grades'
```
### Generators, yield
A generator, instead of returning something, it "yields" something. When you access it, it will "return" the first value generated, then, you can access it again and it will return the next value generated. So, all the values are not generated at the same time and a lot of memory could be saved using this instead of a list with all the values.
from **itertools** import product --> Generates combinations between 1 or more lists, perhaps repeating values, cartesian product \(distributive property\)
from **itertools** import **permutations** --> Generates combinations of all characters in every position
print list\(permutations\(\['1','2','3'\]\)\) = \[\('1', '2', '3'\), \('1', '3', '2'\), \('2', '1', '3'\),... Every posible combination
print\(list\(permutations\('123',2\)\)\) = \[\('1', '2'\), \('1', '3'\), \('2', '1'\), \('2', '3'\), \('3', '1'\), \('3', '2'\)\] Every posible combination of lenght 2
**combinations**
from itertools import **combinations** --> Generates all possible combinations without repeating characters \(if "ab" existing, doesn't generate "ba"\)
from itertools import **combinations\_with\_replacement** --> Generates all possible combinations from the char onwards\(for example, the 3rd is mixed from the 3rd onwards but not with the 2nd o first\)
Decorator that size the time that a function needs to be executed \(from [here](https://towardsdatascience.com/decorating-functions-in-python-619cbbe82c74)\):