Skip to content

Commit 100e26d

Browse files
committed
lists and tuples
1 parent bc6c8af commit 100e26d

File tree

7 files changed

+276
-6
lines changed

7 files changed

+276
-6
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@ everything should also work on Python 3.2 and all newer Pythons.
3131
5. [Variables, Booleans and None](variables.md)
3232
6. [Using functions](using-functions.md)
3333
7. [If, else and elif](if.md)
34-
8. [ThinkPython: Lists](lists.md)
35-
9. [Handy stuff with strings](handy-stuff-strings.md)
34+
8. [Handy stuff with strings](handy-stuff-strings.md)
35+
9. [Lists and tuples](lists-and-tuples.md)
3636
10. [Loops](loops.md)
3737
11. [Trey Hunner: zip and enumerate](trey-hunner-zip-and-enumerate.md)
3838
12. [Files](files.md)

handy-stuff-strings.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,10 @@ True
213213
>>>
214214
```
215215

216+
The things in square brackets that the split method gave us and
217+
we gave to the join method were lists. We'll talk more about
218+
them [later](lists-and-tuples.md).
219+
216220
## String formatting
217221

218222
To add a string in the middle of another string, we can do something
@@ -260,9 +264,6 @@ our problem:
260264
`'Hello {}.'.format(name)`. I like to use printf-formatting for simple
261265
things and `.format` when I need more powerful features.
262266

263-
**TODO:** warn readers about formatting tuples, and show experienced
264-
users that dictionaries aren't a problem
265-
266267
```py
267268
>>> "Hello %s." % name
268269
'Hello Akuli.'
@@ -273,7 +274,7 @@ our problem:
273274

274275
In the second example we had `(name, channel, network)` on the right
275276
side of the `%` sign. It was a tuple, and we'll talk more about them
276-
later.
277+
[later](lists-and-tuples.md#tuples).
277278

278279
If we have a variable that may be a tuple we need to wrap it in another
279280
tuple when formatting:

images/differentlist.png

2.65 KB
Loading

images/drawings.odg

4.18 KB
Binary file not shown.

images/people.png

15.4 KB
Loading

images/samelist.png

2.75 KB
Loading

lists-and-tuples.md

Lines changed: 269 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,269 @@
1+
# Lists and tuples
2+
3+
## Why should we use lists?
4+
5+
Sometimes we may end up doing something like this.
6+
7+
```py
8+
name1 = 'wub_wub'
9+
name2 = 'theelous3'
10+
name3 = 'RubyPinch'
11+
name4 = 'go|dfish'
12+
name5 = 'Nitori'
13+
14+
name = input("Enter your name: ")
15+
if name == name1 or name == name2 or name == name3 or name == name4 or name == name5:
16+
print("I know you!")
17+
else:
18+
print("Sorry, I don't know who you are :(")
19+
```
20+
21+
This code works just fine, but there's a problem. The name check
22+
is repetitive, and adding a new name requires adding even more
23+
repetitive, boring checks.
24+
25+
## Our first list
26+
27+
Instead of adding a new variable for each name it might be
28+
better to store all names in one variable. This means that our
29+
one variable needs to point to multiple values. An easy way to
30+
do this is using a list:
31+
32+
```py
33+
names = ['wub_wub', 'theelous3', 'RubyPinch', 'go|dfish', 'Nitori']
34+
```
35+
36+
Here the `names` variable points to a list, which then points to
37+
strings, like this:
38+
39+
![List of names.](images/people.png)
40+
41+
## What can we do with lists?
42+
43+
Let's open the `>>>` prompt and create a name list.
44+
45+
```py
46+
>>> names = ['wub_wub', 'theelous3', 'RubyPinch', 'go|dfish', 'Nitori']
47+
>>> names
48+
['wub_wub', 'theelous3', 'RubyPinch', 'go|dfish', 'Nitori']
49+
>>>
50+
```
51+
52+
There's many things [we can do with strings](handy-stuff-strings.md),
53+
and some of these things also work with lists.
54+
55+
```py
56+
>>> len(names) # we have 5 names
57+
5
58+
>>> names + ['Akuli'] # create a new list with me in it
59+
['wub_wub', 'theelous3', 'RubyPinch', 'go|dfish', 'Nitori', 'Akuli']
60+
>>> ['theelous3', 'RubyPinch'] * 2 # repeating
61+
['theelous3', 'RubyPinch', 'theelous3', 'RubyPinch']
62+
>>>
63+
```
64+
65+
With strings indexing and slicing both returned a string, but
66+
with lists we get a new list when we're slicing and an element
67+
from the list if we're indexing.
68+
69+
```py
70+
>>> names[:2] # first two names
71+
['wub_wub', 'theelous3']
72+
>>> names[0] # the first name
73+
'wub_wub'
74+
>>>
75+
```
76+
77+
If we want to check if the program knows a name all we need to
78+
do is to use the `in` keyword.
79+
80+
```py
81+
>>> 'lol' in names
82+
False
83+
>>> 'RubyPinch' in names
84+
True
85+
>>>
86+
```
87+
88+
We can't use this for checking if a list of names is a part of
89+
our name list.
90+
91+
```py
92+
>>> ['RubyPinch', 'go|dfish'] in names
93+
False
94+
>>> ['RubyPinch'] in names
95+
False
96+
>>>
97+
```
98+
99+
Lists have a few [useful
100+
methods](https://docs.python.org/3/tutorial/datastructures.html#more-on-lists).
101+
Some of the most commonly used ones are append, extend and
102+
remove. append adds an item to the end of a list, extend adds
103+
multiple items from another list and remove removes an item.
104+
105+
```py
106+
>>> names
107+
['wub_wub', 'theelous3', 'RubyPinch', 'go|dfish', 'Nitori']
108+
>>> names.remove('theelous3') # sorry theelous3
109+
>>> names.remove('go|dfish') # and sorry go|dfish
110+
>>> names
111+
['wub_wub', 'RubyPinch', 'Nitori']
112+
>>> names.append('Akuli') # let's add me here
113+
>>> names
114+
['wub_wub', 'RubyPinch', 'Nitori', 'Akuli']
115+
>>> names.extend(['go|dfish', 'theelous3']) # wb guys
116+
>>> names
117+
['wub_wub', 'RubyPinch', 'Nitori', 'Akuli', 'go|dfish', 'theelous3']
118+
>>>
119+
```
120+
121+
As you can see, **list can be changed in-place**. In other
122+
words, they are **mutable**. Integers, floats, strings and many
123+
other built-in types can't, so they are **immutable**.
124+
125+
With [strings](handy-stuff-strings.md) we did something to them
126+
and then set the result back to the same variable, like
127+
`message = message.strip()`. This just doesn't work right with
128+
most mutable things because they're designed to be changed in-place.
129+
130+
```py
131+
>>> names = names.remove('Akuli')
132+
>>> print(names) # now it's None!
133+
None
134+
>>>
135+
```
136+
137+
This is the same thing that happened way back when [we assigned
138+
print's return value to a variable](using-functions.md).
139+
140+
## What is what?
141+
142+
After working with lists a while you'll find out that they
143+
behave like this:
144+
145+
```py
146+
>>> a = [1, 2, 3]
147+
>>> b = a
148+
>>> b.append(4)
149+
>>> a # this changed also!
150+
[1, 2, 3, 4]
151+
>>>
152+
```
153+
154+
This can be confusing at first, but it's actually easy to
155+
explain. The problem with this code example is the `b = a`
156+
line. If we draw a diagram of this example it looks like this:
157+
158+
![Same list.](images/samelist.png)
159+
160+
This is when the `is` keyword comes in. It can be used to
161+
check if two variables point to the **same** thing.
162+
163+
```py
164+
>>> a is b
165+
True
166+
>>>
167+
```
168+
169+
Typing `[]` creates a **new** list every time.
170+
171+
```py
172+
>>> [] is []
173+
False
174+
>>>
175+
```
176+
177+
If we need a new list with the same content we can use the
178+
`copy` method:
179+
180+
```py
181+
>>> a = [1, 2, 3]
182+
>>> b = a.copy()
183+
>>> b is a
184+
False
185+
>>> b.append(4)
186+
>>> a
187+
[1, 2, 3]
188+
>>>
189+
```
190+
191+
If you're using Python 3.2 or older you can do `a[:]` instead
192+
of `a.copy()`. `a[:]` is a slice of the whole list, just like
193+
`a[0:]`.
194+
195+
## Tuples
196+
197+
Tuples are a lot like lists, but they're immutable so they
198+
can't be changed in-place. We create them like lists, but
199+
with `()` instead of `[]`.
200+
201+
```py
202+
>>> thing = (1, 2, 3)
203+
>>> thing
204+
(1, 2, 3)
205+
>>> thing = ()
206+
>>> thing
207+
()
208+
>>>
209+
```
210+
211+
If we need to create a tuple that contains only one item we
212+
need to use `(item,)` instead of `(item)` because `(item)` is
213+
used in places like `(1 + 2) * 3`.
214+
215+
```py
216+
>>> (3)
217+
3
218+
>>> (3,)
219+
(3,)
220+
>>> (1 + 2) * 3
221+
9
222+
>>> (1 + 2,) * 3
223+
(3, 3, 3)
224+
>>>
225+
```
226+
227+
Tuples don't have methods like append, extend and remove
228+
because they can't change theirselves in-place.
229+
230+
```py
231+
>>> stuff = (1, 2, 3)
232+
>>> stuff.append(4)
233+
Traceback (most recent call last):
234+
File "<stdin>", line 1, in <module>
235+
AttributeError: 'tuple' object has no attribute 'append'
236+
>>>
237+
```
238+
239+
So, why the heck would we use tuples instead of lists? There's
240+
a few cases when we don't want mutability, but there's also
241+
cases when Python programmers just like to use tuples. If you
242+
want to know more about this you can read [Ned Batchelder's blog
243+
post about this](http://nedbatchelder.com/blog/201608/lists_vs_tuples.html).
244+
245+
## Summary
246+
247+
- Lists are a way to point to multiple values with just one variable.
248+
- Lists can be changed in-place and they have methods that change them
249+
in-place, like append, extend and remove.
250+
- Slicing lists returns a **new** list, and indexing them returns an
251+
item from them.
252+
- `thing = another_thing` does not create a copy of `another_thing`.
253+
- Tuples are like lists, but they can't be changed in-place. They're
254+
also used in different places.
255+
256+
## Examples
257+
258+
Here's the same program we had in the beginning of this tutorial, but
259+
using a list:
260+
261+
```py
262+
namelist = ['wub_wub', 'theelous3', 'RubyPinch', 'go|dfish', 'Nitori']
263+
264+
name = input("Enter your name: ")
265+
if name in namelist:
266+
print("I know you!")
267+
else:
268+
print("Sorry, I don't know who you are :(")
269+
```

0 commit comments

Comments
 (0)