The most flexible and useful data types in Python, in my opinion, are lists and tuples. They are present in almost all non-trivial Python programmes. This course will teach you about the key traits of lists and tuples, among other things. You’ll discover how to categorise and control them. By the time you’re done, you ought to understand when and how to use these object kinds in a Python application. Test your knowledge with our interactive quiz on “Python Lists and Tuples.” Take the Quiz » You will be given a score after completing the exercise, allowing you to monitor your ongoing progress in studying.
Python Lists
A list, which is more versatile than an array in many other programming languages, is just a collection of arbitrary items. Python defines lists by enclosing a comma-delimited list of objects in square brackets ([]), as shown.
below:
>>>
>>> a = ['foo', 'bar', 'baz', 'qux']
>>> print(a)
['foo', 'bar', 'baz', 'qux']
>>> a
['foo', 'bar', 'baz', 'qux']
The key features of Python lists are as follows:
follows:
- Lists are ordered.
- Lists can contain any arbitrary objects.
- List elements can be accessed by index.
- Lists can be nested to arbitrary depth.
- Lists are mutable.
- Lists are dynamic.
We analyse each of these characteristics in further depth.
below.
Lists Are Ordered
A list is more than just a list of things. It is an organised grouping of things. A list’s inherent property and one that is preserved throughout the list’s existence is the order in which the components are specified when the list is defined. (In the next instruction on dictionaries, you will encounter a Python data type that is not ordered.)
Lists with identical components in a different arrangement are not the same thing as
same:
>>>
>>> a = ['foo', 'bar', 'baz', 'qux']
>>> b = ['baz', 'qux', 'bar', 'foo']
>>> a == b
False
>>> a is b
False
>>> [1, 2, 3, 4] == [4, 1, 3, 2]
False
Lists Can Contain Arbitrary Objects
Everything may be included in a list of items. A list’s components might all be the same.
type:
>>>
>>> a = [2, 4, 6, 8]
>>> a
[2, 4, 6, 8]
Instead, the components could come in different forms.
types:
>>>
>>> a = [21.42, 'foobar', 3, 4, 'bark', False, 3.14159]
>>> a
[21.42, 'foobar', 3, 4, 'bark', False, 3.14159]
Even complicated things like functions, classes, and modules, which you will discover in following lessons, may be found in lists.
tutorials:
>>>
>>> int
<class 'int'>
>>> len
<built-in function len>
>>> def foo():
... pass
...
>>> foo
<function foo at 0x035B9030>
>>> import math
>>> math
<module 'math' (built-in)>
>>> a = [int, len, foo, math]
>>> a
[<class 'int'>, <built-in function len>, <function foo at 0x02CA2618>,
<module 'math' (built-in)>]
A list may have any number of items in it, from 0 to as much RAM your machine has.
allow:
>>>
>>> a = []
>>> a
[]
>>> a = [ 'foo' ]
>>> a
['foo']
>>> a = [0, 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]
>>> a
[0, 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]
(A singleton list is another name for a list that contains just one item.)
List items don’t have to be exclusive. A single item may appear in a list more than once.
times:
>>>
>>> a = ['bark', 'meow', 'woof', 'bark', 'cheep', 'bark']
>>> a
['bark', 'meow', 'woof', 'bark', 'cheep', 'bark']
List Elements Can Be Accessed by Index
An index enclosed in square brackets may be used to retrieve specific list items. This is the same as accessing certain characters inside a string. As with strings, list indexing uses a zero-based system.
Think about the following
list:
>>>
>>> a = ['foo', 'bar', 'baz', 'qux', 'quux', 'corge']
The following table lists the indices for the items in a:
Index Lists
This Python code allows you to access some components of a
:
>>>
>>> a[0]
'foo'
>>> a[2]
'baz'
>>> a[5]
'corge'
Almost all aspects of string indexing are the same for lists. A negative list index, for instance, starts counting at the end of the list:
Indexing Negative Lists
>>>
>>> a[-1]
'corge'
>>> a[-2]
'quux'
>>> a[-5]
'bar'
It also works to slice. The formula a[m:n] retrieves the section of a from index m to index n, excluding index n, if an is a list.
:
>>>
>>> a = ['foo', 'bar', 'baz', 'qux', 'quux', 'corge']
>>> a[2:5]
['baz', 'qux', 'quux']
List slicing functions similarly to other string slicing functionalities.
well:
-
Both positive and negative indices can be specified:
>>>
>>> a[-5:-2] ['bar', 'baz', 'qux'] >>> a[1:4] ['bar', 'baz', 'qux'] >>> a[-5:-2] == a[1:4] True
-
Omitting the first index starts the slice at the beginning of the list, and omitting the second index extends the slice to the end of the list:
>>>
>>> print(a[:4], a[0:4]) ['foo', 'bar', 'baz', 'qux'] ['foo', 'bar', 'baz', 'qux'] >>> print(a[2:], a[2:len(a)]) ['baz', 'qux', 'quux', 'corge'] ['baz', 'qux', 'quux', 'corge'] >>> a[:4] + a[4:] ['foo', 'bar', 'baz', 'qux', 'quux', 'corge'] >>> a[:4] + a[4:] == a True
-
You can specify a stride—either positive or negative:
>>>
>>> a[0:6:2] ['foo', 'baz', 'quux'] >>> a[1:6:2] ['bar', 'qux', 'corge'] >>> a[6:0:-2] ['corge', 'qux', 'bar']
-
The syntax for reversing a list works the same way it does for strings:
>>>
>>> a[::-1] ['corge', 'quux', 'qux', 'baz', 'bar', 'foo']
-
The
[:]
syntax works for lists. However, there is an important difference between how this operation works with a list and how it works with a string.If
s
is a string,
s[:]
returns a reference to the same object:
>>>
>>> s = 'foobar' >>> s[:] 'foobar' >>> s[:] is s True
Conversely, if
a
is a list,
a[:]
returns a new object that is a copy of
a
:
>>>
>>> a = ['foo', 'bar', 'baz', 'qux', 'quux', 'corge'] >>> a[:] ['foo', 'bar', 'baz', 'qux', 'quux', 'corge'] >>> a[:] is a False
Numerous Python built-in functions and operators may also be used with lists in a manner similar to
strings:
-
The
in
and
not in
operators:
>>>
>>> a ['foo', 'bar', 'baz', 'qux', 'quux', 'corge'] >>> 'qux' in a True >>> 'thud' not in a True
-
The concatenation (
+
) and replication (
*
) operators:
>>>
>>> a ['foo', 'bar', 'baz', 'qux', 'quux', 'corge'] >>> a + ['grault', 'garply'] ['foo', 'bar', 'baz', 'qux', 'quux', 'corge', 'grault', 'garply'] >>> a * 2 ['foo', 'bar', 'baz', 'qux', 'quux', 'corge', 'foo', 'bar', 'baz', 'qux', 'quux', 'corge']
-
The
len()
,
min()
, and
max()
functions:
>>>
>>> a ['foo', 'bar', 'baz', 'qux', 'quux', 'corge'] >>> len(a) 6 >>> min(a) 'bar' >>> max(a) 'qux'
The similarity in behaviour between strings and lists is not by chance. Each of these are special examples of the iterable object type, which is more broadly defined. You will learn more about iterables in the forthcoming course on definite iteration.
By the way, before performing an operation on the list in each of the aforementioned examples, it is always allocated to a variable. Nevertheless, you may use a list literal as
well:
>>>
>>> ['foo', 'bar', 'baz', 'qux', 'quux', 'corge'][2]
'baz'
>>> ['foo', 'bar', 'baz', 'qux', 'quux', 'corge'][::-1]
['corge', 'quux', 'qux', 'baz', 'bar', 'foo']
>>> 'quux' in ['foo', 'bar', 'baz', 'qux', 'quux', 'corge']
True
>>> ['foo', 'bar', 'baz'] + ['qux', 'quux', 'corge']
['foo', 'bar', 'baz', 'qux', 'quux', 'corge']
>>> len(['foo', 'bar', 'baz', 'qux', 'quux', 'corge'][::-1])
6
You could also use a string to do the same thing.
literal:
>>>
>>> 'If Comrade Napoleon says it, it must be right.'[::-1]
'.thgir eb tsum ti ,ti syas noelopaN edarmoC fI'
Lists Can Be Nested
You already know that any kind of object may be an element in a list. There is also another list there. A list may go to any depth by including sublists, which can then include further sublists, and so on.
Think about this (admittedly contrived)
example:
>>>
>>> x = ['a', ['bb', ['ccc', 'ddd'], 'ee', 'ff'], 'g', ['hh', 'ii'], 'j']
>>> x
['a', ['bb', ['ccc', 'ddd'], 'ee', 'ff'], 'g', ['hh', 'ii'], 'j']
The following diagram represents the object hierarchy that x refers to:
An ordered list
x[0], x[2], and x[4] are character-only strings.
long:
>>>
>>> print(x[0], x[2], x[4])
a g j
Nevertheless, x[1] and x[3] are
sublists:
>>>
>>> x[1]
['bb', ['ccc', 'ddd'], 'ee', 'ff']
>>> x[3]
['hh', 'ii']
Add an extra list item to access the items in a sublist.
index:
>>>
>>> x[1]
['bb', ['ccc', 'ddd'], 'ee', 'ff']
>>> x[1][0]
'bb'
>>> x[1][1]
['ccc', 'ddd']
>>> x[1][2]
'ee'
>>> x[1][3]
'ff'
>>> x[3]
['hh', 'ii']
>>> print(x[3][0], x[3][1])
hh ii
Adding one more index accesses the sublist x[1][1], which is still another sublist.
elements:
>>>
>>> x[1][1]
['ccc', 'ddd']
>>> print(x[1][1][0], x[1][1][1])
ccc ddd
There is no limit to the intricacy or depth of list nesting in this manner, other than the size of your computer’s memory.
The standard syntax for indices and slicing is applicable to sublists as well.
well:
>>>
>>> x[1][1][-1]
'ddd'
>>> x[1][1:3]
[['ccc', 'ddd'], 'ee']
>>> x[3][::-1]
['ii', 'hh']
Nevertheless, keep in mind that operators and functions are not recursive and only apply to the list at the level you specify. Think about what occurs when you use len to query the length of x. ()
:
>>>
>>> x
['a', ['bb', ['ccc', 'ddd'], 'ee', 'ff'], 'g', ['hh', 'ii'], 'j']
>>> len(x)
5
>>> x[0]
'a'
>>> x[1]
['bb', ['ccc', 'ddd'], 'ee', 'ff']
>>> x[2]
'g'
>>> x[3]
['hh', 'ii']
>>> x[4]
'j'
Just three strings and two sublists make up x’s five components. The length of x does not include the individual entries in the sublists.
While use the in, a similar situation would arise.
operator:
>>>
>>> 'ddd' in x
False
>>> 'ddd' in x[1]
False
>>> 'ddd' in x[1][1]
True
‘ddd’ is not a part of x or x[1] and is not an element. It only functions as a direct member of the sublist x[1][1]. A sublist’s individual elements do not qualify as parent elements.
list(s).
Lists Are Mutable
The majority of the data types you have come across so far are atomic kinds. For instance, integer or float objects are basic units that cannot be further subdivided. These types are immutable, which means that once they have been allocated, they cannot be modified. It doesn’t make much sense to consider modifying an integer’s value. You may just assign a different number if you wish one.
The string type, in comparison, is a composite type. Strings may be broken down into their component characters for easier analysis. The idea of altering the characters in a string could make sense. You can’t, however. Strings are also immutable in Python.
The first mutable data type you’ve come across is the list. A list’s components may be changed at any time by adding, removing, shifting, and moving them about. Python offers several options to change
lists.
Modifying a Single List Value
Indexing and easy substitution may replace a single value in a list.
assignment:
>>>
>>> a = ['foo', 'bar', 'baz', 'qux', 'quux', 'corge']
>>> a
['foo', 'bar', 'baz', 'qux', 'quux', 'corge']
>>> a[2] = 10
>>> a[-1] = 20
>>> a
['foo', 'bar', 10, 'qux', 'quux', 20]
If you remember from the instruction
Python does not provide the handling of strings and character data in such a
string:
>>>
>>> s = 'foobarbaz'
>>> s[2] = 'x'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'str' object does not support item assignment
The del key may be used to remove a list item.
command:
>>>
>>> a = ['foo', 'bar', 'baz', 'qux', 'quux', 'corge']
>>> del a[3]
>>> a
['foo', 'bar', 'baz', 'quux', 'corge']
Modifying Multiple List Values
What happens if you wish to update a number of adjacent entries in a list all at once? Python permits this because
slice assignment has the following properties.
syntax:
a[m:n] = <iterable>
Once again, consider an iterable as a list for the time being. With this assignment, the provided slice of an is changed to an iterable.
:
>>>
>>> a = ['foo', 'bar', 'baz', 'qux', 'quux', 'corge']
>>> a[1:4]
['bar', 'baz', 'qux']
>>> a[1:4] = [1.1, 2.2, 3.3, 4.4, 5.5]
>>> a
['foo', 1.1, 2.2, 3.3, 4.4, 5.5, 'quux', 'corge']
>>> a[1:6]
[1.1, 2.2, 3.3, 4.4, 5.5]
>>> a[1:6] = ['Bark!']
>>> a
['foo', 'Bark!', 'quux', 'corge']
It’s not necessary for the number of components changed and those added to be equal. Python simply expands or compresses the list as necessary.
Use a slice that only indicates one to substitute many items for a single element.
element:
>>>
>>> a = [1, 2, 3]
>>> a[1:2] = [2.1, 2.2, 2.3]
>>> a
[1, 2.1, 2.2, 2.3, 3]
Keep in mind that this is not the same as substituting a single element for a
list:
>>>
>>> a = [1, 2, 3]
>>> a[1] = [2.1, 2.2, 2.3]
>>> a
[1, [2.1, 2.2, 2.3], 3]
A list may also have things added to it without anything being taken off. Just define a zero-length slice of the type [n:n] at the desired
index:
>>>
>>> a = [1, 2, 7, 8]
>>> a[2:2] = [3, 4, 5, 6]
>>> a
[1, 2, 3, 4, 5, 6, 7, 8]
By giving the right slice to an empty list, you may remove several entries from the centre of a list. The del statement may be used in conjunction with the same
slice:
>>>
>>> a = ['foo', 'bar', 'baz', 'qux', 'quux', 'corge']
>>> a[1:5] = []
>>> a
['foo', 'corge']
>>> a = ['foo', 'bar', 'baz', 'qux', 'quux', 'corge']
>>> del a[1:5]
>>> a
['foo', 'corge']
Prepending or Appending Items to a List
The + concatenation operator or the += operator may be used to add extra items to the beginning or end of a list.
additional assignment operator
:
>>>
>>> a = ['foo', 'bar', 'baz', 'qux', 'quux', 'corge']
>>> a += ['grault', 'garply']
>>> a
['foo', 'bar', 'baz', 'qux', 'quux', 'corge', 'grault', 'garply']
>>> a = ['foo', 'bar', 'baz', 'qux', 'quux', 'corge']
>>> a = [10, 20] + a
>>> a
[10, 20, 'foo', 'bar', 'baz', 'qux', 'quux', 'corge']
Since a list must be concatenated with another list, you must define the element as a singleton if you wish to add just one.
list:
>>>
>>> a = ['foo', 'bar', 'baz', 'qux', 'quux', 'corge']
>>> a += 20
Traceback (most recent call last):
File "<pyshell#58>", line 1, in <module>
a += 20
TypeError: 'int' object is not iterable
>>> a += [20]
>>> a
['foo', 'bar', 'baz', 'qux', 'quux', 'corge', 20]
Note:
Strictly speaking, it is not quite accurate to state that two lists must be concatenated. A list and an iterable object must be concatenated specifically. Lists are iterable by nature, therefore joining two lists together successfully.
Strings may also be iterated. But see what occurs when you combine a string with a
list:
>>>
>>> a = ['foo', 'bar', 'baz', 'qux', 'quux']
>>> a += 'corge'
>>> a
['foo', 'bar', 'baz', 'qux', 'quux', 'c', 'o', 'r', 'g', 'e']
This outcome may not be exactly what you were hoping for. A list of the characters that make up a string is produced after each iteration. A list of the characters in the string “corge” is concatenated onto list an in the example above.
You must designate it as a singleton if all you want to do is add the word “corge” at the end of the list.
list:
>>>
>>> a = ['foo', 'bar', 'baz', 'qux', 'quux']
>>> a += ['corge']
>>> a
['foo', 'bar', 'baz', 'qux', 'quux', 'corge']
Don’t worry too much if something appears enigmatic. The lesson on definite gives you information about iterables, including how they work.
iteration.
Methods That Modify a List
Lastly, there are a number of built-in methods for modifying lists that are provided by Python. The following provides details on these techniques.
Note:
The previous tutorial’s string methods did not directly alter the target string. This is due to strings’ immutability. Instead, string methods return a brand-new string object that has undergone the method’s specified modifications. The first target string is dropped.
unchanged:
>>>
>>> s = 'foobar'
>>> t = s.upper()
>>> print(s, t)
foobar FOOBAR
There are several list approaches. The list techniques shown here alter the target list in situ since lists are changeable.
a.append(
adds a new item to a list. The command a.append(obj) adds the item obj to the end of the list a.
:
>>>
>>> a = ['a', 'b']
>>> a.append(123)
>>> a
['a', 'b', 123]
Keep in mind that list methods change the existing target list. They do not provide a fresh one.
list:
>>>
>>> a = ['a', 'b']
>>> x = a.append(123)
>>> print(x)
None
>>> a
['a', 'b', 123]
If the target operand is an iterable, keep in mind that its items are separated and added to the list when the + operator is used to concatenate to a list.
individually:
>>>
>>> a = ['a', 'b']
>>> a + [1, 2, 3]
['a', 'b', 1, 2, 3]
That is not how the.append() function works! When using.append() to append an iterable to a list, it is inserted as a single item.
object:
>>>
>>> a = ['a', 'b']
>>> a.append([1, 2, 3])
>>> a
['a', 'b', [1, 2, 3]]
Therefore you may attach a string as a single to another using.append().
entity:
>>>
>>> a = ['a', 'b']
>>> a.append('foo')
>>> a
['a', 'b', 'foo']
a.extend(
extends a list with the iterable’s objects.
.extend() similarly adds to the end of a list, but the argument is anticipated to be an iterable, so it is likely what you believe it is. Iterable’s products are added.
individually:
>>>
>>> a = ['a', 'b']
>>> a.extend([1, 2, 3])
>>> a
['a', 'b', 1, 2, 3]
Therefore,.extend() acts similarly to the + operator. More specifically, since it alters the list already in use, it functions as the +=
operator:
>>>
>>> a = ['a', 'b']
>>> a += [1, 2, 3]
>>> a
['a', 'b', 1, 2, 3]
insert (a, index, object)
adds a new object to a list.
The command a.insert(“index”, “obj”) inserts the item “obj” at the specified “index” in the list “a.” The method call results in a[index>] being set to “obj” and the remaining list members being put to the
right:
>>>
>>> a = ['foo', 'bar', 'baz', 'qux', 'quux', 'corge']
>>> a.insert(3, 3.14159)
>>> a[3]
3.14159
>>> a
['foo', 'bar', 'baz', 3.14159, 'qux', 'quux', 'corge']
a.remove(
removes a list item from it.
The function a.remove(obj) removes the item obj from the list a. An exception is triggered if object isn’t in a
raised:
>>>
>>> a = ['foo', 'bar', 'baz', 'qux', 'quux', 'corge']
>>> a.remove('baz')
>>> a
['foo', 'bar', 'qux', 'quux', 'corge']
>>> a.remove('Bark!')
Traceback (most recent call last):
File "<pyshell#13>", line 1, in <module>
a.remove('Bark!')
ValueError: list.remove(x): x not in list
a.pop(index=-1)
removes a list item from it.
Two things set this function different from.remove()
ways:
- You specify the index of the item to remove, rather than the object itself.
- The method returns a value: the item that was removed.
Simply put, a.pop() eliminates the last item in the
list:
>>>
>>> a = ['foo', 'bar', 'baz', 'qux', 'quux', 'corge']
>>> a.pop()
'corge'
>>> a
['foo', 'bar', 'baz', 'qux', 'quux']
>>> a.pop()
'quux'
>>> a
['foo', 'bar', 'baz', 'qux']
The item at that index is deleted and returned if the optional index> argument is used. In the case of strings and lists, index> may be negative.
indexing:
>>>
>>> a = ['foo', 'bar', 'baz', 'qux', 'quux', 'corge']
>>> a.pop(1)
'bar'
>>> a
['foo', 'baz', 'qux', 'quux', 'corge']
>>> a.pop(-3)
'qux'
>>> a
['foo', 'baz', 'quux', 'corge']
Because index> always defaults to -1, a.pop(-1) is the same as a.pop ()
.
Lists Are Dynamic
Six distinguishing traits of Python lists were listed at the start of this session. Lists are dynamic is the last point. In the sections above, you have seen several illustrations of this. Whenever anything is added to a list, it expands as
needed:
>>>
>>> a = ['foo', 'bar', 'baz', 'qux', 'quux', 'corge']
>>> a[2:2] = [1, 2, 3]
>>> a += [3.14159]
>>> a
['foo', 'bar', 1, 2, 3, 'baz', 'qux', 'quux', 'corge', 3.14159]
Similar to how a list becomes shorter when something is removed
items:
>>>
>>> a = ['foo', 'bar', 'baz', 'qux', 'quux', 'corge']
>>> a[2:3] = []
>>> del a[0]
>>> a
['bar', 'qux', 'quux', 'corge']
Python Tuples
A tuple, which is another type offered by Python, is an ordered group of items.
What people pronounce differently depends on who they ask. Some pronounce it “too-ple” (rhyming with “Mott the Hoople”), while others call it “tup-ple” (rhyming with “supple”). My preference is the latter because everyone I know pronounces the later as if it rhymes with “quintuple,” “sextuple,” “octuple,” and so on, which are all derived from the same root.
“supple.”
Defining and Using Tuples
In every way, tuples and lists are the same, except the following exception:
properties:
-
Tuples are defined by enclosing the elements in parentheses (
()
) instead of square brackets (
[]
). - Tuples are immutable.
This is a brief illustration of the definition, indexing, and use of a tuple.
slicing:
>>>
>>> t = ('foo', 'bar', 'baz', 'qux', 'quux', 'corge')
>>> t
('foo', 'bar', 'baz', 'qux', 'quux', 'corge')
>>> t[0]
'foo'
>>> t[-1]
'corge'
>>> t[1::2]
('bar', 'qux', 'corge')
Fear not! Tuples are compatible with our preferred string and list reversal technique as
well:
>>>
>>> t[::-1]
('corge', 'quux', 'qux', 'baz', 'bar', 'foo')
You still index and slice tuples using square brackets, exactly as for strings and lists, even though tuples are formed using parentheses.
Tuples have all the same characteristics as lists, including their order, ability to include any kind of object, ability to be indexed and sliced, and ability to be nested. Therefore, they can’t
modified:
>>>
>>> t = ('foo', 'bar', 'baz', 'qux', 'quux', 'corge')
>>> t[2] = 'Bark!'
Traceback (most recent call last):
File "<pyshell#65>", line 1, in <module>
t[2] = 'Bark!'
TypeError: 'tuple' object does not support item assignment
Why not use a tuple rather than a
list?
-
Program execution is faster when manipulating a tuple than it is for the equivalent list. (This is probably not going to be noticeable when the list or tuple is small.)
-
Sometimes you don’t want data to be modified. If the values in the collection are meant to remain constant for the life of the program, using a tuple instead of a list guards against accidental modification.
-
There is another Python data type that you will encounter shortly called a dictionary, which requires as one of its components a value that is of an immutable type. A tuple can be used for this purpose, whereas a list can’t be.
You may show the values of many objects in a Python REPL session at once by explicitly entering them at the >>> prompt, separated by
commas:
>>>
>>> a = 'foo'
>>> b = 42
>>> a, 3.14159, b
('foo', 3.14159, 42)
Due to Python’s implicit interpretation of the input as a tuple, the answer is shown in parentheses.
You should be aware of one oddity with respect to tuple definition. Whether defining an empty tuple or one with two or more items, there is no room for ambiguity. Python is aware that you’re declaring a
tuple:
>>>
>>> t = ()
>>> type(t)
<class 'tuple'>
>>>
>>> t = (1, 2)
>>> type(t)
<class 'tuple'>
>>> t = (1, 2, 3, 4, 5)
>>> type(t)
<class 'tuple'>
So, what happens if you attempt to construct a tuple with one
item:
>>>
>>> t = (2)
>>> type(t)
<class 'int'>
Oops! Python treats the expression (2) as just the number 2 and constructs an int object since parentheses are also used to indicate operator precedence in expressions. A trailing comma (,) should be included shortly before the closing bracket to signal to Python that you really wish to construct a singleton tuple.
parenthesis:
>>>
>>> t = (2,)
>>> type(t)
<class 'tuple'>
>>> t[0]
2
>>> t[-1]
2
There must be a mechanism to create a singleton tuple even if you probably won’t need to do it often.
Python adds the comma when you present a singleton tuple to let you know that it’s a single object.
tuple:
>>>
>>> print(t)
(2,)
Tuple Assignment, Packing, and Unpacking
A literal tuple with numerous components may be assigned to a single value, as you have previously seen in the example above.
object:
>>>
>>> t = ('foo', 'bar', 'baz', 'qux')
When this happens, the tuple’s components seem to have been “packed” into the object:
Doubling up
>>>
>>> t
('foo', 'bar', 'baz', 'qux')
>>> t[0]
'foo'
>>> t[-1]
'qux'
The separate elements are “unpacked” into the objects in the tuple if that “packed” object is later allocated to a different tuple:
Unpacking in piles
>>>
>>> (s1, s2, s3, s4) = t
>>> s1
'foo'
>>> s2
'bar'
>>> s3
'baz'
>>> s4
'qux'
The number of variables on the left must equal the number of values on the right when unpacking.
tuple:
>>>
>>> (s1, s2, s3) = t
Traceback (most recent call last):
File "<pyshell#16>", line 1, in <module>
(s1, s2, s3) = t
ValueError: too many values to unpack (expected 3)
>>> (s1, s2, s3, s4, s5) = t
Traceback (most recent call last):
File "<pyshell#17>", line 1, in <module>
(s1, s2, s3, s4, s5) = t
ValueError: not enough values to unpack (expected 5, got 4)
You may form a compound statement by combining the words “packing” and “unpacking” together.
assignment:
>>>
>>> (s1, s2, s3, s4) = ('foo', 'bar', 'baz', 'qux')
>>> s1
'foo'
>>> s2
'bar'
>>> s3
'baz'
>>> s4
'qux'
The number of members in the tuple to the left of the assignment must match the number on the right.
right:
>>>
>>> (s1, s2, s3, s4, s5) = ('foo', 'bar', 'baz', 'qux')
Traceback (most recent call last):
File "<pyshell#63>", line 1, in <module>
(s1, s2, s3, s4, s5) = ('foo', 'bar', 'baz', 'qux')
ValueError: not enough values to unpack (expected 5, got 4)
Python permits the parentheses that are typically used to indicate a tuple to be left out in assignments like this one and a select few other circumstances.
out:
>>>
>>> t = 1, 2, 3
>>> t
(1, 2, 3)
>>> x1, x2, x3 = t
>>> x1, x2, x3
(1, 2, 3)
>>> x1, x2, x3 = 4, 5, 6
>>> x1, x2, x3
(4, 5, 6)
>>> t = 2,
>>> t
(2,)
If you’re unsure of whether parenthesis are required, add them anyhow since it doesn’t matter whether they are or not.
Tuple assignment permits an intriguing example of idiomatic Python. You often need to swap the values of two variables while programming. Most programming languages require that one of the values be kept in a temporary variable while the swap is happening, such as
this:
>>>
>>> a = 'foo'
>>> b = 'bar'
>>> a, b
('foo', 'bar')
>>># We need to define a temp variable to accomplish the swap.
>>> temp = a
>>> a = b
>>> b = temp
>>> a, b
('bar', 'foo')
A single tuple may be used to do the swap in Python.
assignment:
>>>
>>> a = 'foo'
>>> b = 'bar'
>>> a, b
('foo', 'bar')
>>># Magic time!
>>> a, b = b, a
>>> a, b
('bar', 'foo')
Being able to swap values using a temporary variable in Python is the height of contemporary technical accomplishment, as everyone who has ever had to do so can attest. Nothing could possibly be better than this.