Skip to content

Commit 06030c8

Browse files
committed
WIP day 2
1 parent 5b31046 commit 06030c8

2 files changed

Lines changed: 131 additions & 0 deletions

File tree

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
### Converting between types
2+
* `str(value)` - stringify something. Handles numbers, None. Even collection types are stringified
3+
```python
4+
str(['hello', 'world']) # "['hello', 'world']"
5+
str({ "key1": "value1", "key2": 35 }) # "{'key1': 'value1', 'key2': 35}"
6+
```
7+
* `int(value)` - only accepts numbers or strings that looks like integers
8+
* `float(value)` - only accepts numbers or strings that looks like numbers
9+
10+
Python has `split` and `join` methods to explode or implode lists/strings.
11+
```python
12+
'hello world'.split(' ') # ['hello', 'world']
13+
' '.join(['hello', 'world']) # 'hello world'
14+
```
15+
Note that with `join`, the syntax is `delimiter_string.join(list)`
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
# Advanced looping
2+
3+
https://www.learnpython.dev/03-intermediate-python/20-advanced-looping/10-list-comprehensions/
4+
5+
## List comprehensions
6+
Sorta similar to the `.map()` and `.filter()` and other array methods in JS. Convenient powerful shorthands for making lists.
7+
8+
Say you want to iterate through a list, perform an operation on each item that produces a new value, and return a new list with those new values. You would use `.map()` in JS, but in python you can do a list comprehension. List comprehensions put an entire expression inside the square brackets:
9+
10+
```python
11+
names = ['jimmy', 'susan', 'peter']
12+
[name.upper() for name in names] # ['JIMMY', 'SUSAN', 'PETER']
13+
```
14+
15+
So the syntax is kind of like:
16+
```python
17+
[ transform(thing) for thing in list_of_things ]
18+
```
19+
20+
```python
21+
[num * num for num in range(6)] # [0, 1, 4, 9, 16, 25]
22+
```
23+
24+
You can add a conditional filtering mechanism at the end of a list comprehension. Say you want to do the above squaring operation but only on the even numbers:
25+
26+
```python
27+
[num * num for num in range(6) if num % 2 == 0] # [0, 4, 16]
28+
```
29+
30+
## Set comprehension
31+
Works very similarly for transforming a list into a set
32+
33+
```python
34+
{ num * num for num in range(10) }
35+
# {0, 1, 64, 4, 36, 9, 16, 49, 81, 25}
36+
```
37+
38+
## Dictionary comprehension
39+
Construct a key:value expression in your transformation step to create a dictionary from a list:
40+
```python
41+
{ num: num * num for num }
42+
# {0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25}
43+
```
44+
45+
## Generator expressions (comprehensions)
46+
Generators are iterables that generate values on demand, instead of loading a massive list into memory. They return a generator, not a list.
47+
48+
Wrap the comprehension expression in parentheses instead of square brackets to make a generator expression.
49+
50+
```python
51+
gen = (x ** 2 for x in range(10) if x % 2 == 0)
52+
type(gen) # <class 'generator'>
53+
```
54+
55+
You can use a generator in place of list in a lot of expressions. Note that once a generator has been fully iterated, it is now empty and functions as an empty array when used:
56+
57+
```python
58+
gen = (x ** 2 for x in range(10) if x % 2 == 0)
59+
# use the above generator to make a set. each number is computed on the fly
60+
{ v for v in gen } # {0, 64, 4, 36, 16}
61+
62+
max(gen) # ValueError: max() arg is an empty sequence
63+
64+
# reinstantiate generator (important because the above loop ran through the iterator leaving it empty)
65+
gen = (x ** 2 for x in range(10) if x % 2 == 0)
66+
max(gen) # 64
67+
```
68+
69+
Generator are generated when you put them in a comprehension, or a for loop, or when calling `next(generator)` is called.
70+
71+
## Slicing
72+
Any ordered sequence (list, tuple, or string ) can be sliced. It's not a method, it's just a special indexing syntax. You apply the square bracket syntax with `[starting_index: ending_index: step]` where `starting_index` is included by `ending_index` is not. `step` defaults to 1:
73+
74+
```python
75+
letters = ['a', 'b', 'c', 'd', 'e']
76+
letters[0:2] # ['a', 'b']
77+
letters[1:3] # ['b', 'c']
78+
# when starting index is omitted, it starts from the beginning
79+
letters[:3] # ['a', 'b', 'c']
80+
# when ending index is omitted, it goes to the end
81+
letters[2:] # ['c', 'd', 'e']
82+
letters[-2:] # ['d', 'e']
83+
```
84+
85+
Assigning `new_list = some_list`, we have not created two lists. We have just created a pointer to `some_list`. Thus any mutations to `new_list` would also be reflected on `some_list`. Sometimes you want to clone a list so that you can modify the clone without updating the original. __Slicing with both indeces omitted does this__
86+
87+
```python
88+
some_list = [1, 2, 3]
89+
a_new_list = some_list[:]
90+
# only modifies `a_new_list`
91+
a_new_list.append(4)
92+
# use a -1 step to clone a list in reverse
93+
reverse_list = some_list(::-1)
94+
# [3, 2, 1]
95+
```
96+
97+
## Zip
98+
You have two different lists, and you want to unify them by index, where the first item in list 1 is grouped with the first item in list 2, etc. `zip(l1, l2)` does that.
99+
```python
100+
players = ['Susy', 'Alex', 'Roberto']
101+
scores = [88, 78, 92]
102+
zipped = zip(players, scores)
103+
type(zipped) # <class 'zip'>
104+
```
105+
106+
A zip object is kind of like an iterable. It's not immediately explorable without throwing it in a loop, comprehension, or calling `next(zipped)`. What you'll see is that each item in the zip iterable is a tuple:
107+
108+
```python
109+
# convert iterable to list to see what's inside
110+
scorecards = list(zip(players, scores))
111+
# [('Susy', 88), ('Alex', 78), ('Roberto', 92)]
112+
113+
# or turn it into a dict
114+
scorecards = list(zip(players, scores))
115+
# {'Susy': 88, 'Alex': 78, 'Roberto': 92}
116+
```

0 commit comments

Comments
 (0)