finished native-datatypes, except for sets

This commit is contained in:
Mark Pilgrim
2009-03-13 11:39:06 -04:00
parent 5602bc3384
commit a9b82eab12
2 changed files with 138 additions and 9 deletions
+1
View File
@@ -22,6 +22,7 @@ h1:before{content:""}
<li>jQuery is served by <a href=http://code.google.com/apis/ajaxlibs/>Google AJAX Libraries API</a>.
<li>Other Javascript and CSS resources are minimized by <a href=http://developer.yahoo.com/yui/compressor/>YUI Compressor</a>.
<li>HTTP caching and other server-side options are optimized based on advice from <a href=http://developer.yahoo.com/yslow/>YSlow</a>.
<li>The text uses Unicode characters in place of graphics wherever possible.
<li>The entire book was lovingly hand-authored in HTML 5. View-source; I typed that.
</ol>
<p class=c>&copy; 2001&ndash;4, 2009 <span>&#x2133;</span>ark Pilgrim
+137 -9
View File
@@ -22,12 +22,20 @@ body{counter-reset:h1 2}
<li><a href=#divingin>Diving in</a>
<li><a href=#booleans>Booleans</a>
<li><a href=#numbers>Numbers</a>
<ol>
<li><a href=#number-coercion>Coercing integers to floats and vice-versa</a>
<li><a href=#common-numerical-operations>Common numerical operations</a>
<li><a href=#fractions>Fractions</a>
<li><a href=#trig>Trigonometry</a>
<li><a href=#numbers-in-a-boolean-context>Numbers in a boolean context</a>
</ol>
<li><a href=#lists>Lists</a>
<ol>
<li><a href=#creatinglists>Creating a list</a>
<li><a href=#slicinglists>Slicing a list</a>
<li><a href=#extendinglists>Adding items to a list</a>
<li><a href=#searchinglists>Searching for values in a list</a>
<li><a href=#lists-in-a-boolean-context>Lists in a boolean context</a>
</ol>
<!--
<li><a href=#sets>Sets</a>
@@ -40,7 +48,16 @@ body{counter-reset:h1 2}
</ol>
-->
<li><a href=#dictionaries>Dictionaries</a>
<ol>
<li><a href=#creating-dictionaries>Creating a dictionary</a>
<li><a href=#modifying-dictionaries>Modifying a dictionary</a>
<li><a href=#mixed-value-dictionaries>Mixed-value dictionaries</a>
<li><a href=#dictionaries-in-a-boolean-context>Dictionaries in a boolean context</a>
</ol>
<li><a href=#none><code>None</code></a>
<ol>
<li><a href=#none-in-a-boolean-context><code>None</code> in a boolean context</a>
</ol>
<li><a href=#furtherreading>Further reading</a>
</ol>
<h2 id=divingin>Diving in</h2>
@@ -90,6 +107,7 @@ body{counter-reset:h1 2}
<li>Adding an <code>int</code> to an <code>int</code> yields an <code>int</code>.
<li>Adding an <code>int</code> to a <code>float</code> yields a <code>float</code>. Python coerces the <code>int</code> into a <code>float</code> to perform the addition, then returns a <code>float</code> as the result.
</ol>
<h3 id=number-coercion>Coercing integers to floats and vice-versa</h3>
<p>As you just saw, some operators (like addition) will coerce integers to floating point numbers as needed. You can also coerce them by yourself.
<pre class=screen>
<a><samp class=prompt>>>> </samp><kbd>float(2)</kbd> <span>&#x2460;</span></a>
@@ -115,6 +133,7 @@ body{counter-reset:h1 2}
<blockquote class="note compare python2">
<p><span>&#x261E;</span>Python 2 had separate types for <code>int</code> and <code>long</code>. The <code>int</code> datatype was limited by <code>sys.maxint</code>, which varied by platform but was usually <code>2<sup>32</sup>-1</code>. Python 3 has just one integer type, which behaves mostly like the old <code>long</code> type from Python 2. See <a href=http://www.python.org/dev/peps/pep-0237><abbr>PEP</abbr> 237</a> for details.
</blockquote>
<h3 id=common-numerical-operations>Common numerical operations</h3>
<p>You can do all kinds of things with numbers.
<pre class=screen>
<a><samp class=prompt>>>> </samp><kbd>11 / 2</kbd> <span>&#x2460;</span></a>
@@ -141,7 +160,68 @@ body{counter-reset:h1 2}
<blockquote class="note compare python2">
<p><span>&#x261E;</span>In Python 2, the <code>/</code> operator usually meant integer division, but you could make it behave like floating point division by including a special directive in your code. In Python 3, the <code>/</code> operator always means floating point division. See <a href=http://www.python.org/dev/peps/pep-0238/><abbr>PEP</abbr> 238</a> for details.
</blockquote>
<p>FIXME fractions, math module, numbers in a boolean context
<h3 id=fractions>Fractions</h3>
<p>Python isn't limited to integers and floating point numbers. It can also do all the fancy math you learned in high school and promptly forgot about.
<pre class=screen>
<a><samp class=prompt>>>> </samp><kbd>import fractions</kbd> <span>&#x2460;</span></a>
<a><samp class=prompt>>>> </samp><kbd>x = fractions.Fraction(1, 3)</kbd> <span>&#x2461;</span></a>
<samp class=prompt>>>> </samp><kbd>x</kbd>
<samp>Fraction(1, 3)</samp>
<a><samp class=prompt>>>> </samp><kbd>x * 2</kbd> <span>&#x2462;</span></a>
<samp>Fraction(2, 3)</samp>
<a><samp class=prompt>>>> </samp><kbd>fractions.Fraction(6, 4)</kbd> <span>&#x2463;</span></a>
<samp>Fraction(3, 2)</samp></code></pre>
<ol>
<li>To start using fractions, import the <code>fractions</code> module.
<li>To define a fraction, create a <code>Fraction</code> object and pass in the numerator and denominator.
<li>You can perform all the usual mathematical operations with fractions. Operations return a new <code>Fraction</code> object. <code>2 * (1/3) = (2/3)</code>
<li>The <code>Fraction</code> object will automatically reduce fractions. <code>(6/4) = (3/2)</code>
</ol>
<h3 id=trig>Trigonometry</h3>
<p>You can also do basic trigonometry in Python.
<pre class=screen>
<samp class=prompt>>>> </samp><kbd>import math</kbd>
<a><samp class=prompt>>>> </samp><kbd>math.pi</kbd> <span>&#x2460;</span></a>
<samp>3.1415926535897931</samp>
<a><samp class=prompt>>>> </samp><kbd>math.sin(math.pi / 2)</kbd> <span>&#x2461;</span></a>
<samp>1.0</samp>
<a><samp class=prompt>>>> </samp><kbd>math.tan(math.pi / 4)</kbd> <span>&#x2462;</span></a>
<samp>0.99999999999999989</samp></pre>
<ol>
<li>The <code>math</code> module has a constant for &pi;, the ratio of a circle's circumference to its diameter.
<li>The <code>math</code> module has all the basic trigonometric functions, including <code>sin()</code>, <code>cos()</code>, <code>tan()</code>, and variants like <code>asin()</code>.
<li>Note, however, that Python does not have infinite precision. <code>tan(&pi; / 4)</code> should return <code>1.0</code>, not <code>0.99999999999999989</code>.
</ol>
<h3 id=numbers-in-a-boolean-context>Numbers in a boolean context</h3>
<p>You can use numbers <a href="#booleans">in a boolean context</a>, such as an <code>if</code> statement. Zero values are false, and non-zero values are true.
<pre class=screen>
<a><samp class=prompt>>>> </samp><kbd>def is_it_true(anything):</kbd> <span>&#x2460;</span></a>
<samp class=prompt>... </samp><kbd> if anything:</kbd>
<samp class=prompt>... </samp><kbd> print("yes, it's true")</kbd>
<samp class=prompt>... </samp><kbd> else:</kbd>
<samp class=prompt>... </samp><kbd> print("no, it's false")</kbd>
<samp class=prompt>...</samp>
<a><samp class=prompt>>>> </samp><kbd>is_it_true(1)</kbd> <span>&#x2461;</span></a>
<samp>yes, it's true</samp>
<samp class=prompt>>>> </samp><kbd>is_it_true(-1)</kbd>
<samp>yes, it's true</samp>
<samp class=prompt>>>> </samp><kbd>is_it_true(0)</kbd>
<samp>no, it's false</samp>
<a><samp class=prompt>>>> </samp><kbd>is_it_true(0.1)</kbd> <span>&#x2462;</span></a>
<samp>yes, it's true</samp>
<samp class=prompt>>>> </samp><kbd>is_it_true(0.0)</kbd>
<samp>no, it's false</samp>
<samp class=prompt>>>> </samp><kbd>import fractions</kbd>
<a><samp class=prompt>>>> </samp><kbd>is_it_true(fractions.Fraction(1, 2))</kbd> <span>&#x2463;</span></a>
<samp>yes, it's true</samp>
<samp class=prompt>>>> </samp><kbd>is_it_true(fractions.Fraction(0, 1))</kbd>
<samp>no, it's false</samp></pre>
<ol>
<li>Did you know you can define your own functions in the Python interactive shell? Just press <kbd>ENTER</kbd> at the end of each line, and <kbd>ENTER</kbd> on a blank line to finish.
<li>In a boolean context, non-zero integers are true; <code>0</code> is false.
<li>Non-zero floating point numbers are true; <code>0.0</code> is false. Be careful with this one! If there's the slightest rounding error (not impossible, as you saw in the previous section) then Python will be testing <code>0.0000000000001</code> instead of <code>0</code> and will return <code>True</code>.
<li>Fractions can also be used in a boolean context. <code>Fraction(0, n)</code> is false for all values of <var>n</var>. All other fractions are true.
</ol>
<h2 id=lists>Lists</h2>
<p>Lists are Python's workhorse datatype. When I say &#8220;list,&#8221; you might be thinking &#8220;array whose size I have to declare in advance, that can only contain items of the same type, <i class=baa>&amp;</i>c.&#8221; Don't think that. Lists are much cooler than that.
<blockquote class="note compare perl5">
@@ -263,6 +343,23 @@ ValueError: list.index(x): x not in list</samp></pre>
<li>The <code>index()</code> method finds the <em>first</em> occurrence of a value in the list. In this case, <code>'new'</code> occurs twice in the list, in <code>a_list[2]</code> and <code>a_list[4]</code>, but the <code>index()</code> method will return only the index of the first occurrence.
<li>As you might <em>not</em> expect, if the value is not found in the list, Python raises an exception. This is notably different from most languages, which will return some invalid index (like <code>-1</code>). While this may seem annoying at first, I think you will come to appreciate it. It means your program will crash at the source of the problem instead of failing strangely and silently later.
</ol>
<h3 id=lists-in-a-boolean-context>Lists in a boolean context</h3>
<p>You can also use a list in <a href=#booleans>a boolean context</a>, such as an <code>if</code> statement.
<pre class=screen>
<a><samp class=prompt>>>> </samp><kbd>def is_it_true(anything):</kbd> <span>&#x2460;</span></a>
<samp class=prompt>... </samp><kbd> if anything:</kbd>
<samp class=prompt>... </samp><kbd> print("yes, it's true")</kbd>
<samp class=prompt>... </samp><kbd> else:</kbd>
<samp class=prompt>... </samp><kbd> print("no, it's false")</kbd>
<samp class=prompt>...</samp>
<a><samp class=prompt>>>> </samp><kbd>is_it_true([])</kbd> <span>&#x2461;</span></a>
<samp>no, it's false</samp>
<a><samp class=prompt>>>> </samp><kbd>is_it_true(['a'])</kbd> <span>&#x2462;</span></a>
<samp>yes, it's true</samp></pre>
<ol>
<li>In a boolean context, an empty list is false.
<li>Any list with at least one item is true.
</ol>
<!--
<h2 id=sets>Sets</h2>
<p>FIXME
@@ -272,6 +369,7 @@ ValueError: list.index(x): x not in list</samp></pre>
<blockquote class="note compare perl5">
<p><span>&#x261E;</span>A dictionary in Python is like a hash in Perl 5. In Perl 5, variables that store hashes always start with a <code>%</code> character. In Python, variables can be named anything, and Python keeps track of the datatype internally.
</blockquote>
<h3 id=creating-dictionaries>Creating a dictionary</h3>
<p>Creating a dictionary is easy. The syntax is similar to <a href=#sets>sets</a>, but instead of values, you have key-value pairs. Once you have a dictionary, you can look up values by their key.
<pre class=screen>
<a><samp class=prompt>>>> </samp><kbd>a_dict = {"server":"db.diveintopython3.org", "database":"mysql"}</kbd> <span>&#x2460;</span></a>
@@ -291,6 +389,7 @@ KeyError: 'db.diveintopython3.org'</samp></pre>
<li><code>'database'</code> is a key, and its associated value, referenced by <code>a_dict["database"]</code>, is <code>'mysql'</code>.
<li>You can get values by key, but you can't get keys by value. So <code>a_dict["server"]</code> is <code>'db.diveintopython3.org'</code>, but <code>a_dict["db.diveintopython3.org"]</code> raises an exception, because <code>'db.diveintopython3.org'</code> is not a key.
</ol>
<h3 id=modifying-dictionaries>Modifying a dictionary</h3>
<p>Dictionaries do not have any predefined size limit. You can add new key-value pairs to a dictionary at any time, or you can modify the value of an existing key. Continuing from the previous example:
<pre class=screen>
<samp class=prompt>>>> </samp><kbd>a_dict</kbd>
@@ -314,6 +413,7 @@ KeyError: 'db.diveintopython3.org'</samp></pre>
<li>Assigning a value to an existing dictionary key simply replaces the old value with the new one.
<li>Will this change the value of the <code>user</code> key back to "mark"? No! Look at the key closely &mdash; that's a capital <kbd>U</kbd> in <kbd>"User"</kbd>. Dictionary keys are case-sensitive, so this statement is creating a new key-value pair, not overwriting an existing one. It may look similar to you, but as far as Python is concerned, it's completely different.
</ol>
<h3 id=mixed-value-dictionaries>Mixed-value dictionaries</h3>
<p>Dictionaries aren't just for strings. Dictionary values can be any datatype, including integers, booleans, arbitrary objects, or even other dictionaries. And within a single dictionary, the values don't all need to be the same type; you can mix and match as needed. Dictionary keys are more restricted, but they can be strings, integers, and a few other types. You can also mix and match key datatypes within a dictionary.
<p>In fact, you've already seen a dictionary with non-string keys and values, in <a href=your-first-python-program.html#divingin>your first Python program</a>.
<pre><code>SUFFIXES = {1000: ('KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'),
@@ -331,13 +431,30 @@ KeyError: 'db.diveintopython3.org'</samp></pre>
<a><samp class=prompt>>>> </samp><kbd>SUFFIXES[1000][3]</kbd> <span>&#x2463;</span></a>
<samp>'TB'</samp></pre>
<ol>
<li>As with <a href=#lists>lists</a> and <a href=#sets>sets</a>, the <code>len()</code> function gives you the number of items in a dictionary.
<li>As with <a href=#lists>lists</a><!-- and <a href=#sets>sets</a>-->, the <code>len()</code> function gives you the number of items in a dictionary.
<li><code>1000</code> is a key in the <code>SUFFIXES</code> dictionary; its value is a list of eight items (eight strings, to be precise).
<li>Similarly, <code>1024</code> is a key in the <code>SUFFIXES</code> dictionary; its value is also a list of eight items.
<li>Since <code>SUFFIXES[1000]</code> is a list, you can address individual items in the list by their 0-based index.
</ol>
<h3 id=dictionaries-in-a-boolean-context>Dictionaries in a boolean context</h3>
<p>You can also use a list in <a href=#booleans>a boolean context</a>, such as an <code>if</code> statement.
<pre class=screen>
<a><samp class=prompt>>>> </samp><kbd>def is_it_true(anything):</kbd> <span>&#x2460;</span></a>
<samp class=prompt>... </samp><kbd> if anything:</kbd>
<samp class=prompt>... </samp><kbd> print("yes, it's true")</kbd>
<samp class=prompt>... </samp><kbd> else:</kbd>
<samp class=prompt>... </samp><kbd> print("no, it's false")</kbd>
<samp class=prompt>...</samp>
<a><samp class=prompt>>>> </samp><kbd>is_it_true({})</kbd> <span>&#x2461;</span></a>
<samp>no, it's false</samp>
<a><samp class=prompt>>>> </samp><kbd>is_it_true({'a': 1})</kbd> <span>&#x2462;</span></a>
<samp>yes, it's true</samp></pre>
<ol>
<li>In a boolean context, an empty dictionary is false.
<li>Any dictionary with at least one key-value pair is true.
</ol>
<h2 id=none><code>None</code></h2>
<p><code>None</code> is a special constant in Python. It is a null value. <code>None</code> is not <code>False</code>; it is not <code>0</code>; it is not an empty string. Comparing <code>None</code> to anything other than <code>None</code> will always return <code>False</code>.
<p><code>None</code> is a special constant in Python. It is a null value. <code>None</code> is not the same as <code>False</code>. <code>None</code> is not <code>0</code>. <code>None</code> is not an empty string. Comparing <code>None</code> to anything other than <code>None</code> will always return <code>False</code>.
<p><code>None</code> is the only null value. It has its own datatype (<code>NoneType</code>). You can assign <code>None</code> to any variable, but you can not create other <code>NoneType</code> objects. All variables whose value is <code>None</code> are equal to each other.
<pre class=screen>
<samp class=prompt>>>> </samp><kbd>type(None)</kbd>
@@ -357,14 +474,25 @@ KeyError: 'db.diveintopython3.org'</samp></pre>
<samp class=prompt>>>> </samp><kbd>x == y</kbd>
<samp>True</samp>
</pre>
<h3 id=none-in-a-boolean-context><code>None</code> in a boolean context</h3>
<p>In <a href=#booleans>a boolean context</a>, <code>None</code> is false and <code>not None</code> is true.
<pre class=screen>
<a><samp class=prompt>>>> </samp><kbd>def is_it_true(anything):</kbd>
<samp class=prompt>... </samp><kbd> if anything:</kbd>
<samp class=prompt>... </samp><kbd> print("yes, it's true")</kbd>
<samp class=prompt>... </samp><kbd> else:</kbd>
<samp class=prompt>... </samp><kbd> print("no, it's false")</kbd>
<samp class=prompt>...</samp>
<a><samp class=prompt>>>> </samp><kbd>is_it_true(None)</kbd>
<samp>no, it's false</samp>
<a><samp class=prompt>>>> </samp><kbd>is_it_true(not None)</kbd>
<samp>yes, it's true</samp></pre>
<h2 id=furtherreading>Further reading</h2>
<ul>
<li>fractions
<li>math module
<li><abbr>PEP</abbr> 237
<li><abbr>PEP</abbr> 238
<li>links to appendix
<li>...etc...
<li><a href="http://docs.python.org/dev/3.0/library/fractions.html">The <code>fractions</code> module</a>
<li><a href="http://docs.python.org/dev/3.0/library/math.html">The <code>math</code> module</a>
<li><a href="http://www.python.org/dev/peps/pep-0237/"><abbr>PEP</abbr> 237: Unifying Long Integers and Integers</a>
<li><a href="http://www.python.org/dev/peps/pep-0238/"><abbr>PEP</abbr> 238: Changing the Division Operator</a>
</ul>
<p class=c>&copy; 2001&ndash;4, 2009 <span>&#x2133;</span>ark Pilgrim &#8226; <a href=about.html>open standards &#8226; open content &#8226; open source</a>
<script src=jquery.js></script>