mercoledì 4 novembre 2015

A crash course in Python - Lesson 2: Lists

A fundamental data structure is the list. A list is an ordered collection of data. This does NOT mean that values are ordered in a specific order (i.e., either ascending or descending). Instead, it means that elements can be accessed in an ordered way, starting from index 0 to index (length-1).

A list can be seen as an array with some added functionality, and a great (and very important!) difference: while an array stores homogeneous values (i.e., values having the same type), a list can store heterogeneous values.

Instantiating a list

The following two lines show how to declare:

  • a homogeneous list (i.e., a list containing values having the same data type);
  • a heterogeneous list (i.e., a list containing values having different data types).

homogeneous_list_of_integers = [1, 2, 3]
heterogeneous_list = ["string", 0.1, True]

A list can also be generated via the range function, which includes all the values in a range:
list = range(10) # [0,1,...,9]

Element types

Note: list elements can be lists too:
list_of_lists = [homogenous_list, heterogeneous_list, []]

Accessing to elements

It is possible to access to list elements in the following way:
first = list[0]  # first element in the list
last = list[-1]  # last element of the list
next_to_last = list[-2]  # next_to_last element of the list

Check if a list contains an element

Python has an in operator to check for list membership:
1 in [0, 1, 2]  # True
3 in [0, 1, 2]  # False

Slicing lists

You can use square brackets to slice lists:
first_three_elements = list[:3]  #index 3 is EXCLUDED
three_to_end = list[3:]  #index 3 is INCLUDED
one_to_four = list[1:5]  #index 1 is included, 
                         # index 5 is excluded
without_first_and_last = list[1:-1] # 0 and -1 are excluded
last_three = list[-3:]
copy_of_x = list[:]

Concatenate lists

It is easy to concatenate lists together:
x = [1, 2, 3]
x.extend([4, 5, 6])  # Now x is [1,2,3,4,5,6]

However, one can decide to avoid the modification of the original list, by using list addition:
x = [1, 2, 3]
y = x + [4, 5, 6]
# Now y = [1, 2, 3, 4, 5, 6]
# while x is unchanged

It is also possible to append lists one item at a time:
x = [1, 2, 3]
x.append(0)

Store the list content in separate variables

It is often convenient to unpack lists if you know exactly how many elements they contain:
x, y = [1, 2]  # Now x = 1 and y = 2

Notice that if you are not interested in extracting and storing all the values in the list, you can decide to ignore some values:
_, y = [1, 2]  #Now y = 2 and we did not care about the first element

Some special functionalities

Lists have specific functionalities that allow one to manipulate easily their data.

For instance, the following computes the length of a list:
list_length = len(list)

The following, instead, computes the sum of the elements of the list:
list_sum = sum(list)

Creating lists via for loops

You may want to transform a list into another list, by choosing only certain elements, or by transforming elements, or both. This operation is called list comprehension. You may do this by doing the following:

even_numbers = [x for x in range(5) id x % 2 == 0]
squares = [x * x for x in range(5)]
even_squares = [x * x for x in even_numbers]

The same thing applies for dictionaries or sets: you can transform a list into one of them.

If you do not need the value from the list, you can use an underscore as the variable:
zeroes = [0 for _ in even_numbers]

Finally, you may use multiple for to populate the list:
pairs = [(x, y)
           for x in range(10)
           for y in range(10)]
# 100 pairs: (0,0) (0,1)...(9,8) (9,9)

Sorting lists

Don't implement your own (bubble sort??) sorting algorithm: Python already provides a sorting method for lists!
  • the sort() method is applied on a list x via dot notation (i.e., x.sort()) and sorts the list in place meaning that x will be modified so that its elements will be ordered in ascending order
  • the sorted(L) method takes a list L as parameter and returns a new list, which is a copy of list L, only with ordered elements (in ascending ordered)

x = [4, 1, 2, 3]
y = sorted(x)  # y = [1, 2, 3, 4], x unchanged
x.sort()  # x = [1, 2, 3, 4]

There are a couple of things that you can apply to the sorted function:

  • to sort elements in descending order, you can specify a reverse=True parameter
  • you can compare the results of a function that you specify with the key parameter; the sorted function will order such results instead of the actual elements of the list
x = sorted([-4,1,-2,3], key=abs, reverse=True)  
# result: [-4, 3, -2, 1]

# sort the words and counts from highest count to lowest
wc = sorted(word_counts.items(),
                   key = lambda (word, count): count,
                   reverse=True)

Iterating over elements and indexes: enumerate

You may want to iterate over a list and use both its elements and their indexes. The solution is the enumerate() function which produces tuples of the form
(index, element)
Note: to have further details about what is a tuple and how to use it, see Lesson 4.

To extract such tuples:
for i, anElement in enumerate(myCollection):
    do_something(i, anElement)

Instead, if you just want the indexes:
for i, _ in enumerate(myCollection): do_something(i)

Zipping and unzipping lists

Zipping lists

One may need to zip lists together, i.e., transform multiple lists into a single list of tuples, where each tuple contains elements from the lists having the same index.

list1 = ['a', 'b', 'c']
list2 = [1, 2, 3]
zip(list1, list2)  # [('a',1), ('b',2), ('c',3)]

Unzipping lists 

You can also unzip a list in multiple lists:

pairs = [('a',1), ('b',2), ('c',3)]
letters, numbers = zip(*pairs)

Here, the asterisk performs an argument unpacking, meaning that we will use the elements of pairs as individual arguments to the zip function. This results in the same outcome that you'd obtain by calling:

zip(('a',1), ('b',2), ('c',3))
# result: [('a','b','c'), (1,2,3)]

You can decide to use argument unpacking with any function, as follows:

def add(a,b):
    return a + b

add(1,2)  # returns 3
add([1,2])  # TypeError
add(*[1,2])  # returns 3

Nessun commento:

Posta un commento