Tuesday, 19 September 2017

Manipulating Lists

So previously we've looked at what lists are. Now what can we do with them?
Lists are a mutable data type. This means we can change them without assigning them to a new variable (or recreating the existing variable). However, the order of elements stays put unless we specifically change them. This means you can look at an element at a specific position (also known as the element's index) in a list by the list variable name followed by the position in square brackets. So for example on the command line:
>>> example = [23, 10, 18, 31]
>>> print (example[1])
10
>>>
You might say the computer has got it wrong. That's not the first number in the list, it should be 23.
Remember when using range(10) we actually got a range from 0 to 9? Lists are numbered the same way - from 0 to length-1. So if you wanted the first element, you need [0]
>>> print (example[0])
23
>>>
And just to show you what happens if you try to go beyond the end of a list:
 >>> print(example[5])
Traceback (most recent call last):
  File "<pyshell#4>", line 1, in <module>
    print(example[5])
IndexError: list index out of range

>>>
This is known as an "out of range error" and may crop up if you aren't careful with lists in programs. As you can see, the position of the element is referred to as its index.
To find the last item in a list you can use [-1], so you don't need to know the actual length:
>>> print (example[-1])
31
>>>
You can change an element's value by using its index in an assignment statement
>>> print (example)
[23, 10, 18, 31]
>>> example[1] = 15
>>> print (example)
[23, 15, 18, 31]
>>>
Lists also have a bunch of useful built-in functions, including index(), sort(), append() and clear().

index()

This function looks for the position (index) of an element within a list with the format listname.index(element). If one or more elements match what it's looking for, it returns the index of the first one. Again remember that the index starts at 0 and ends at number of elements -1.
>>> print (example)
[23, 15, 18, 31]
>>> example.index(23)
0
>>> example.index(31)
3
>>> example.index(0)
Traceback (most recent call last):
  File "<pyshell#5>", line 1, in <module>
    example.index(0)
ValueError: 0 is not in list

>>>
As you can see, Python throws an error when asked to give the index of something not in the list so this is not good for generally searching for a term in a list - for that use in

sort()

This allows us to sort a list into some order. Going back to our example on the Python command line
>>> example.sort()
>>> print (example)
[15, 18, 23, 31]
>>> print (example.sort())
None
>>>
That print(example.sort()) is a tricky one that has caught me out several times. The sort() function will sort the list, but returns None. There have been times in a program when I've done something like
>>> newlist = example.sort()
>>> print (newlist)
None
>>>

and then been puzzled and annoyed when the newlist is empty. What I should have done is
>>> newlist = example
>>> newlist.sort()
>>> print (newlist)
[15, 18, 23, 31]
>>>
 One final caveat - when sorting, don't mix types - more specifically, don't try to sort a mix of numbers and strings. sort() can sort numbers (including a mix of floats and integers, such as secondexample below) numerically, and it can sort strings ASCIIbetically (like alphabetically but with a wider range of characters, such as thirdexample below) , but it doesn't sort a mix of numerical and ASCIIbetical (like badexample) and comes back with a type error.
>>> secondexample = [102, 52.3, 75, 10.666, 0.01, 10]
>>> secondexample.sort()
>>> print (secondexample)
[0.01, 10, 10.666, 52.3, 75, 102]
>>> print (type(secondexample[0]))
<class 'float'>
>>> print (type(secondexample[1]))
<class 'int'>
>>> thirdexample = ['this', 'is', 'a', 'list', 'of', 'strings']
>>> thirdexample.sort()
>>> print (thirdexample)
['a', 'is', 'list', 'of', 'strings', 'this']
>>> badexample = [0.2, 'Hello', 'world', 50]
>>> badexample.sort()
Traceback (most recent call last):
  File "<pyshell#42>", line 1, in <module>
    badexample.sort()
TypeError: '<' not supported between instances of 'str' and 'float'

>>>

append()and Concatenation

Adding new elements to the end of a list can be done two ways. One is concatenation (a fancy way of saying sticking two things together, one after the other), the other uses the append() function. So going back to our example on the Python command line:
>>> example = example + [17]
>>> print (example)
[15, 18, 23, 31, 17]
>>> example.append(25)
>>> print (example)
[15, 18, 23, 31, 17, 25]
>>>
At this stage there doesn't seem to be a major difference between the two. However, there are ramifications later on because append() modifies the existing list, while concatenation creates a new list, or at least here recreates the existing list with the addition.
Concatenation has two advantages: firstly you can add new elements onto the front, by doing the concatenation the other way round:
>>> print (example)
[15, 18, 23, 31, 17, 25]
>>> example = [41] + example
>>> print (example)
[41, 15, 18, 23, 31, 17, 25]
>>>

and secondly you can concatenate more than one element at a time, or even join two lists together.
>>> concatexample = secondexample + example
>>> print (concatexample)
[0.01, 10, 10.666, 52.3, 75, 102, 41, 15, 18, 23, 31, 17, 25]
>>>
If you append() one list onto the end of another list, what you get is a list within a list.
>>> print (thirdexample)
['a', 'is', 'list', 'of', 'strings', 'this']
>>> thirdexample.append(badexample)
>>> print (thirdexample)
['a', 'is', 'list', 'of', 'strings', 'this', [0.2, 'Hello', 'world', 50]]
>>>
This might be what you actually want. There are good reasons for having lists within lists. But I need to be careful about this.

del and clear()

Finally you can remove elements from lists. If appending the list into the other list was a mistake, I can use del command and the element's index in the list:
>>> print (thirdexample)
['a', 'is', 'list', 'of', 'strings', 'this', [0.2, 'Hello', 'world', 50]]
>>>
>>> del thirdexample[6]
>>> print (thirdexample)
['a', 'is', 'list', 'of', 'strings', 'this']
>>>
 To totally clear out a list, you can use the clear() function. This doesn't delete the list itself, merely all the elements it contains.
>>> print(badexample)
[0.2, 'Hello', 'world', 50]
>>> badexample.clear()
>>> print (badexample)
[]
>>>


No comments:

Post a Comment