list.extend()

We can append multiple elements at the same time using list.extend.

In [1]:
L = [42, 43, 45]
M = [51, 52]
L.extend(M)
In [2]:
L
Out[2]:
[42, 43, 45, 51, 52]

Of course, we can just repeatedly use append instead:

In [3]:
def my_extend(L, M):
    '''extend the list L using M'''
    for e in M:
        L.append(e)
        
L = [42, 43, 45]
M = [51, 52]
my_extend(L, M)        
In [4]:
L
Out[4]:
[42, 43, 45, 51, 52]

Note that we cannot use append here directly:

In [5]:
L = [42, 43, 45]
M = [51, 52]
L.append(M)
In [6]:
L
Out[6]:
[42, 43, 45, [51, 52]]

What happenned is that we append M as an element, so that the last element of L is the list [51, 52]. This is different from the last two elements of M being [51, 52].

Aside in response to a question in class: slicing for "extending in the middle"

We can use the following in order to "insert" several elements at once in the middle of a list.

In [7]:
L = [42, 43, 45]
M = [51, 52]
L[1:1] = M
In [8]:
L
Out[8]:
[42, 51, 52, 43, 45]

list.sort() and sorted()

Here is how we can sort lists in ascending order.

In [9]:
L = [5, 2, 10, 20, 1]
In [10]:
sorted(L)
Out[10]:
[1, 2, 5, 10, 20]

The value of sorted(L) is a list with the same elements as L, except sorted in ascending order. Note that sorted(L) has a value, but doesn't modify L.

In [11]:
L
Out[11]:
[5, 2, 10, 20, 1]

L is still unchanged! We can of course go

In [12]:
M = sorted(L)
In [13]:
M
Out[13]:
[1, 2, 5, 10, 20]

M will be the sorted version of L.

We can also use list.sort()

In [14]:
L
Out[14]:
[5, 2, 10, 20, 1]
In [15]:
L.sort()
In [16]:
L
Out[16]:
[1, 2, 5, 10, 20]

L.sort() modifies L to be the sorted (in ascending order) version of L. Note that L.sort()'s value is None:

You can sort lists of strings as well. Those are sorted in alphabetical (called, lexicographical) order:

In [17]:
L = ["CSC", "CIV", "PRA", "ESC"]
sorted(L)
Out[17]:
['CIV', 'CSC', 'ESC', 'PRA']

You cannot mix strings and numbers, since you cannot compare them (at least not without additional work)

In [18]:
1 < "one"
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-18-48ab05ebd54a> in <module>()
----> 1 1 < "one"

TypeError: unorderable types: int() < str()
In [19]:
sorted([2, "two", "hello"])
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-19-dadb63996fd2> in <module>()
----> 1 sorted([2, "two", "hello"])

TypeError: unorderable types: str() < int()
In [20]:
L = [3, 1, 5]
M = L.sort()
print(M)
None

Functions that modify the value of lists vs. functions that return a value

Functions like list.insert(), list.append(), list.sort(), etc all modify lists, and return None. On the other hand, len() and sorted() return a value, but do not modify the argument.

Adding lists

If you add lists to each other, the expression with the addition does have a value

In [21]:
L1 = [1, 2]
L2 = [5, 6, 7]
M = L1 + L2
M
Out[21]:
[1, 2, 5, 6, 7]
In [22]:
L1
Out[22]:
[1, 2]

Here, L1 + L2 does have a value. Note that, due to a design quirk, in Python, +=, as applied to lists, works exactly like extend (more on this later.)

In [23]:
L1 = [1, 2]
L2 = [5, 6, 7]
L1 += L2
L1
Out[23]:
[1, 2, 5, 6, 7]