Skip to content

Commit e6d80b0

Browse files
committed
oddities
1 parent 5defb60 commit e6d80b0

2 files changed

Lines changed: 662 additions & 0 deletions

File tree

Lines changed: 331 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,331 @@
1+
{
2+
"metadata": {
3+
"name": "",
4+
"signature": "sha256:437ca0df14a08cf4fd584f91122010286928f287ae14c5ac1ce8230abe9dbf9a"
5+
},
6+
"nbformat": 3,
7+
"nbformat_minor": 0,
8+
"worksheets": [
9+
{
10+
"cells": [
11+
{
12+
"cell_type": "markdown",
13+
"metadata": {},
14+
"source": [
15+
"Sebastian Raschka \n",
16+
"last updated: 04/15/2014"
17+
]
18+
},
19+
{
20+
"cell_type": "markdown",
21+
"metadata": {},
22+
"source": [
23+
"All code was executed in Python 3.4"
24+
]
25+
},
26+
{
27+
"cell_type": "markdown",
28+
"metadata": {},
29+
"source": [
30+
"# A collection of not so obvious Python stuff you should know!"
31+
]
32+
},
33+
{
34+
"cell_type": "markdown",
35+
"metadata": {},
36+
"source": [
37+
"# Sections\n",
38+
"- [The C3 class resolution algorithm for multiple class inheritance](#c3_class_res)\n",
39+
"- [The behavior of += for lists](#pm_in_lists)\n",
40+
"- [`True` and `False` in the datetime module](#datetime_module)\n",
41+
"- [Some Python Oddity that I cannot explain, yet](#python_oddity)\n",
42+
"- [Shallow vs. deep copies if list contains other structures and objects](#shallow_vs_deep)\n",
43+
"- [Picking True values from and and or expressions](#false_true_expressions)"
44+
]
45+
},
46+
{
47+
"cell_type": "markdown",
48+
"metadata": {},
49+
"source": [
50+
"<br>\n",
51+
"<br>\n",
52+
"<a name='c3_class_res'></a>\n",
53+
"## The C3 class resolution algorithm for multiple class inheritance"
54+
]
55+
},
56+
{
57+
"cell_type": "markdown",
58+
"metadata": {},
59+
"source": [
60+
"If we are dealing with multiple inheritance, according to the newer C3 class resolution algorithm, the following applies: \"class A should be checked before class B\".\n",
61+
"\n",
62+
"If you want to learn more, please read the [original blog](http://python-history.blogspot.ru/2010/06/method-resolution-order.html) post by Guido van Rossum.\n",
63+
"\n",
64+
"(Original source: [http://gistroll.com/rolls/21/horizontal_assessments/new](http://gistroll.com/rolls/21/horizontal_assessments/new))"
65+
]
66+
},
67+
{
68+
"cell_type": "code",
69+
"collapsed": false,
70+
"input": [
71+
"class A(object):\n",
72+
" def foo(self):\n",
73+
" print(\"class A\")\n",
74+
"\n",
75+
"class B(object):\n",
76+
" def foo(self):\n",
77+
" print(\"class B\")\n",
78+
"\n",
79+
"class C(A, B):\n",
80+
" pass\n",
81+
"\n",
82+
"C().foo()"
83+
],
84+
"language": "python",
85+
"metadata": {},
86+
"outputs": [
87+
{
88+
"output_type": "stream",
89+
"stream": "stdout",
90+
"text": [
91+
"class A\n"
92+
]
93+
}
94+
],
95+
"prompt_number": 2
96+
},
97+
{
98+
"cell_type": "markdown",
99+
"metadata": {},
100+
"source": [
101+
"<br>\n",
102+
"<br>\n",
103+
"<a name='pm_in_lists'></a>\n",
104+
"## The behavior of `+=` for lists"
105+
]
106+
},
107+
{
108+
"cell_type": "markdown",
109+
"metadata": {},
110+
"source": [
111+
"If we are using the `+=` operator on lists, we extend the list by modifying the object directly. However, if we use the assigment via `my_list = my_list + ...`, we create a new list object, which can be demonstrated by the following code:\n",
112+
"\n",
113+
"(Original source: [http://stackoverflow.com/questions/2347265/why-does-behave-unexpectedly-on-lists](http://stackoverflow.com/questions/2347265/why-does-behave-unexpectedly-on-lists))"
114+
]
115+
},
116+
{
117+
"cell_type": "code",
118+
"collapsed": false,
119+
"input": [
120+
"list_a = []\n",
121+
"print('ID of list_a', id(list_a))\n",
122+
"list_a += [1]\n",
123+
"print('ID of list_a after `+= [1]`', id(list_a))\n",
124+
"list_a = list_a + [2]\n",
125+
"print('ID of list_a after `list_a = list_a + [2]`', id(list_a))"
126+
],
127+
"language": "python",
128+
"metadata": {},
129+
"outputs": [
130+
{
131+
"output_type": "stream",
132+
"stream": "stdout",
133+
"text": [
134+
"ID of list_a 4356439144\n",
135+
"ID of list_a after `+= [1]` 4356439144\n",
136+
"ID of list_a after `list_a = list_a + [2]` 4356446112\n"
137+
]
138+
}
139+
],
140+
"prompt_number": 3
141+
},
142+
{
143+
"cell_type": "markdown",
144+
"metadata": {},
145+
"source": [
146+
"<br>\n",
147+
"<br>\n",
148+
"<a name='datetime_module'></a>\n",
149+
"## `True` and `False` in the datetime module\n",
150+
"\n",
151+
"\"it often comes as a big surprise for programmers to find (sometimes by way of a hard-to-reproduce bug) that,\n",
152+
"unlike any other time value, midnight (i.e. datetime.time(0,0,0)) is False.\n",
153+
"A long discussion on the python-ideas mailing list shows that, while surprising,\n",
154+
"that behavior is desirable\u2014at least in some quarters.\"\n",
155+
"\n",
156+
"(Original source: [http://lwn.net/SubscriberLink/590299/bf73fe823974acea/](http://lwn.net/SubscriberLink/590299/bf73fe823974acea/))"
157+
]
158+
},
159+
{
160+
"cell_type": "code",
161+
"collapsed": false,
162+
"input": [
163+
"import datetime\n",
164+
"\n",
165+
"print('\"datetime.time(0,0,0)\" (Midnight) evaluates to', bool(datetime.time(0,0,0)))\n",
166+
"\n",
167+
"print('\"datetime.time(1,0,0)\" (1 am) evaluates to', bool(datetime.time(1,0,0)))"
168+
],
169+
"language": "python",
170+
"metadata": {},
171+
"outputs": [
172+
{
173+
"output_type": "stream",
174+
"stream": "stdout",
175+
"text": [
176+
"\"datetime.time(0,0,0)\" (Midnight) evaluates to False\n",
177+
"\"datetime.time(1,0,0)\" (1 am) evaluates to True\n"
178+
]
179+
}
180+
],
181+
"prompt_number": 4
182+
},
183+
{
184+
"cell_type": "markdown",
185+
"metadata": {},
186+
"source": [
187+
"<br>\n",
188+
"<br>\n",
189+
"<a name='python_oddity'></a>\n",
190+
"## Some Python Oddity that I cannot explain, yet"
191+
]
192+
},
193+
{
194+
"cell_type": "code",
195+
"collapsed": false,
196+
"input": [
197+
"a = 1\n",
198+
"b = 1\n",
199+
"print('a is b', bool(a is b))\n",
200+
"True\n",
201+
"\n",
202+
"a = 999\n",
203+
"b = 999\n",
204+
"print('a is b', bool(a is b))"
205+
],
206+
"language": "python",
207+
"metadata": {},
208+
"outputs": [
209+
{
210+
"output_type": "stream",
211+
"stream": "stdout",
212+
"text": [
213+
"a is b True\n",
214+
"a is b False\n"
215+
]
216+
}
217+
],
218+
"prompt_number": 5
219+
},
220+
{
221+
"cell_type": "markdown",
222+
"metadata": {},
223+
"source": [
224+
"<br>\n",
225+
"<br>\n",
226+
"<a name='shallow_vs_deep'></a>\n",
227+
"## Shallow vs. deep copies if list contains other structures and objects\n",
228+
"\n",
229+
"List modification of the original list does affect shallow copies, but not deep copies if the list contains compound objects."
230+
]
231+
},
232+
{
233+
"cell_type": "code",
234+
"collapsed": false,
235+
"input": [
236+
"from copy import deepcopy\n",
237+
"\n",
238+
"my_first_list = [[1],[2]]\n",
239+
"my_second_list = [[1],[2]]\n",
240+
"print('my_first_list == my_second_list:', my_first_list == my_second_list)\n",
241+
"print('my_first_list is my_second_list:', my_first_list is my_second_list)\n",
242+
"\n",
243+
"my_third_list = my_first_list\n",
244+
"print('my_first_list == my_third_list:', my_first_list == my_third_list)\n",
245+
"print('my_first_list is my_third_list:', my_first_list is my_third_list)\n",
246+
"\n",
247+
"my_shallow_copy = my_first_list[:]\n",
248+
"print('my_first_list == my_shallow_copy:', my_first_list == my_shallow_copy)\n",
249+
"print('my_first_list is my_shallow_copy:', my_first_list is my_shallow_copy)\n",
250+
"\n",
251+
"my_deep_copy = deepcopy(my_first_list)\n",
252+
"print('my_first_list == my_deep_copy:', my_first_list == my_deep_copy)\n",
253+
"print('my_first_list is my_deep_copy:', my_first_list is my_deep_copy)\n",
254+
"\n",
255+
"print('\\nmy_third_list:', my_third_list)\n",
256+
"print('my_shallow_copy:', my_shallow_copy)\n",
257+
"print('my_deep_copy:', my_deep_copy)\n",
258+
"\n",
259+
"my_first_list[0][0] = 2\n",
260+
"print('after setting \"my_first_list[0][0] = 2\"')\n",
261+
"print('my_third_list:', my_third_list)\n",
262+
"print('my_shallow_copy:', my_shallow_copy)\n",
263+
"print('my_deep_copy:', my_deep_copy)"
264+
],
265+
"language": "python",
266+
"metadata": {},
267+
"outputs": [
268+
{
269+
"output_type": "stream",
270+
"stream": "stdout",
271+
"text": [
272+
"my_first_list == my_second_list: True\n",
273+
"my_first_list is my_second_list: False\n",
274+
"my_first_list == my_third_list: True\n",
275+
"my_first_list is my_third_list: True\n",
276+
"my_first_list == my_shallow_copy: True\n",
277+
"my_first_list is my_shallow_copy: False\n",
278+
"my_first_list == my_deep_copy: True\n",
279+
"my_first_list is my_deep_copy: False\n",
280+
"\n",
281+
"my_third_list: [[1], [2]]\n",
282+
"my_shallow_copy: [[1], [2]]\n",
283+
"my_deep_copy: [[1], [2]]\n",
284+
"after setting \"my_first_list[0][0] = 2\"\n",
285+
"my_third_list: [[2], [2]]\n",
286+
"my_shallow_copy: [[2], [2]]\n",
287+
"my_deep_copy: [[1], [2]]\n"
288+
]
289+
}
290+
],
291+
"prompt_number": 7
292+
},
293+
{
294+
"cell_type": "markdown",
295+
"metadata": {},
296+
"source": [
297+
"<br>\n",
298+
"<br>\n",
299+
"<a name='false_true_expressions'></a>\n",
300+
"## Picking `True` values from `and` and `or` expressions\n",
301+
"\n",
302+
"If both values of in a `or` expression are True, Python will select the first one, and the second one in `and` expressions\n",
303+
"\n",
304+
"(Original source: [http://gistroll.com/rolls/21/horizontal_assessments/new](http://gistroll.com/rolls/21/horizontal_assessments/new))"
305+
]
306+
},
307+
{
308+
"cell_type": "code",
309+
"collapsed": false,
310+
"input": [
311+
"result = (2 or 3) * (5 and 7)\n",
312+
"print('2 * 7 =', result)"
313+
],
314+
"language": "python",
315+
"metadata": {},
316+
"outputs": [
317+
{
318+
"output_type": "stream",
319+
"stream": "stdout",
320+
"text": [
321+
"2 * 7 = 14\n"
322+
]
323+
}
324+
],
325+
"prompt_number": 9
326+
}
327+
],
328+
"metadata": {}
329+
}
330+
]
331+
}

0 commit comments

Comments
 (0)