forked from CalebCurry/python
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path07-dictionaries-sets.py
More file actions
262 lines (177 loc) · 7.68 KB
/
Copy path07-dictionaries-sets.py
File metadata and controls
262 lines (177 loc) · 7.68 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
######### INTRO TO DICTIONARIES #########
#dictionary stores key-value pairs
#The equiv of an associative array/hash table
emails = {
"Caleb":"caleb@email.com",
"Gal":"g@example.com"
}
print(emails)
#in this case, the key is the name, email is the value.
#Data type doesn't matter at all for the value.
#Key must be a hashable --> What does this mean?
#Classes have a function __hash__ invoked when used as the key
print(hash("hello"))
#I'm not sure of exact internals on how the hash is used, but imagine it like so:
#You have an area of memory with 8 spots, and you need to store the value at some spot...
print(hash("hello") % 8)
#Almost always immutable type (should be, anyway)
#a tuple will work, list will not. a number will work
#Why use a hashtable? Extremely fast to add or look up data
#O(1) --> constant time. More elements does not mean slower unlike a sort or something
#https://en.wikipedia.org/wiki/Hash_table
#Hashtables often used for memoization
#Next up we gonna talk about retrieving data from a dictionary
######### RETRIEVE DATA FROM DICTIONARY ##########
print(list(emails))
print(sorted(emails))
#print(emails[0]) # NOPE!
print(emails["Caleb"])
#Since data is not nicely sequenced
#we may want to check before we try grabbing stuff
if("Caleb" in emails):
print("Emailing", emails["Caleb"])
#This may seem bad because we first check to see if its in
#Then we do another line to get the value
#but this is different than a list where we iterate to find the element
#The key is goes through hash to calculate index. Either there or not
#This is O(1)
#You may still not like the casing and in that situation there is a method
print(emails.get("Ryan")) #Returns none if not found
print(emails.get("Ryan", "Not found")) #optional return arg if not found
######### ADD DATA TO DICTIONARY #########
#How to add data (3 ways here):
#indexing
emails["josh"] = "josh@j.com"
print(emails)
#update function
emails.update( {"josh": "evennewer@email.com"})
print(emails)
#Weird variation
emails.update(josh = "new@email.com")
print(emails)
#Key must be hashable
emails[5] = "test"
emails[(1, 2)] = "yep"
#emails[[5, 3]] = "nope" #list is not hashable (mainly cuz mutable)
######### LOOPING THROUGH KEYS #########
#dictionary is an iterable (implements __iter__)
emails = {
"Caleb":"caleb@email.com",
"Gal":"g@example.com",
"Ted": "talk@gmail.com"
}
#k is a variable but k by convention for key
for k in emails:
print(k)
#You can use the key to get the element
#Not ideal.
#One reason being the key has to be hashed to get the value associated with it.
#(but will show better way in next section)
for k in emails:
print("index", k, "is", emails[k])
######### LOOPING THROUGH KEY-VALUE PAIRS #########
#In the prev section we used the index with [].
#Although it works, you can do this:
for k, elem in emails.items():
print(k, elem)
#Each iteration k will be the key and elem will be the item found at this key.
#As an example of what a hashtable can be used for, you can keep track of occurances:
conjunctions = {"but": 0, "or": 0, "so": 0, "and": 0, "yet": 0, "for": 0, "nor": 0} #fanboys
completely_original_poem = """I still hear your voice when you sleep next to me
I still feel your touch in my dreams
Forgive me my weakness, but I don't know why
Without you it's hard to survive
'Cause every time we touch, I get this feeling
And every time we kiss I swear I could fly
Can't you feel my heart beat fast, I want this to last
Need you by my side"""
words = completely_original_poem.split()
for word in words:
if str.lower(word) in conjunctions:
conjunctions[str.lower(word)] += 1
print(conjunctions)
#This could easily be wrapped in a function to take a msg and words to look for, returning a dict
#concept can be used to analyze documents to quantify how vulgar they are, search for phrases, etc
#dictionaries can be used to keep track of values that are hard to calculate (memoization)
######### SETS EXPLAINED #########
#Sets are similar to dictionaries in that the data is hashed and it is unordered.
#Sets are similar to lists in that they just contain the data and not a key-value pair
#Sets are different than lists in that you cannot have duplicates
stuff = {"sword", "rubber duck", "sice a pizza"}
print("sword" in stuff)
print(stuff)
stuff.add("sword")
print(stuff)
#Notice only one occurance of sword even though already added
#How is a set different than a dictionary?
#For a set, each element is only one piece of data
#for a dictionary, it is a key-value pair.
#Behind the scenes, they both use hashing. The hashing is used to determine where to store the data.
#For dictionaries, the KEY is hashed
#for sets, we do not have a key, so the data itself is hashed.
#This means we cannot store something in sets that is not hashable.
#stuff.add(["trying to add a list"])
#It's important to understand the purpose of a set...
#Easily check if element in set
#such as to easily check to see if something has been tagged
#To do various set operations (coming soon)
#An example would be to see if a word is ever used in a phrase. Not counted (that wold be a dictionary)
conjunctions = {"but", "or", "so", "and", "yet", "for", "nor"} #fanboys
seen = set() #THERE'S NOT AN EMPTY SET LITERAL!! #learn something new every day
completely_original_poem = """I still hear your voice when you sleep next to me
I still feel your touch in my dreams
Forgive me my weakness, but I don't know why
Without you it's hard to survive
'Cause every time we touch, I get this feeling
And every time we kiss I swear I could fly
Can't you feel my heart beat fast, I want this to last
Need you by my side"""
words = completely_original_poem.split()
for word in words:
if str.lower(word) in conjunctions:
seen.add(str.lower(word))
print(seen)
######### REMOVE DUPLICATES FROM LIST / CREATE SET FROM LIST ##########
#You can remove duplicate elements from a list by converting it to a set and back.
colors = ["red", "red", "green", "green", "blue", "blue", "blue"]
print(id(colors), colors)
colors[:] = list(set(colors))
print(id(colors), colors)
#Earlier on in our life I showed some code to count each type of element in a list.
colors = ["red", "red", "green", "green", "blue", "blue", "blue"]
counts = [[colors.count(item), item] for item in set(colors)]
print(counts)
#This works because is iterates through the set {"red", "green", "blue"} counting each in colors
######### UNION AND INTERSECTION #########
my_fav = {"red", "green", "black", "blue", "purple"}
her_fav= {"blue", "orange", "purple", "green"}
#union
all_favs = my_fav | her_fav
print(all_favs) #no repetition
#You may see + to combine lists, in which there are repeats.
#But we are not working with lists...so i'll try to focus here.
#intersection (elements shared between both)
wedding_colors = my_fav & her_fav
print(wedding_colors)
#this is like the inside section of a venn diagram
#There are also method versions:
all_favs = my_fav.union(her_fav)
print(all_favs)
wedding_colors = my_fav.intersection(her_fav)
print(wedding_colors)
######### DIFFERENCE AND SYMMETRIC DIFFERENCE #########
my_fav = {"red", "green", "black", "blue", "purple"}
her_fav= {"blue", "orange", "purple", "green"}
#Difference
only_my_colors = my_fav - her_fav
print(only_my_colors) #elements in left getting rid of all in right.
#Could go other way too:
only_her_colors = her_fav - my_fav
print(only_her_colors)
#symmetric difference is like if you took colors only I liked union with colors only she liked and put em together:
symmetric = my_fav ^ her_fav
print(symmetric)
#This is like:
symmetric = only_my_colors | only_her_colors
print(symmetric)
#like union and intersection, there are method versions that return. --> .difference and .symmetric_difference