from IPython.core.display import HTML
HTML(open("custom.html", "r").read())
Python lists collect data, types may be mixed and the list may be as long as your computers memory allows.
There are not type restrictions for the elements of a list
li = [0, 1.0, 2, True, "abc", [1, 2, 3]]
print(li)
[0, 1.0, 2, True, 'abc', [1, 2, 3]]
Some useful, but not all list methods:
words = ["this", "is", "a", "list"]
words.append("in")
words.append("python")
print(words)
['this', 'is', 'a', 'list', 'in', 'python']
Comment: string methods do not change the corresponding string in-place but return a result. append returns None but changes the list in place:
words = ["this", "is", "a", "list"]
words_new = words.append("in")
print("words_new is", words_new)
print("words is", words)
words_new is None words is ['this', 'is', 'a', 'list', 'in']
In case you want to append multiple elements to a list, you can use .extend which takes a list of items:
words = ["this", "is", "a", "list"]
words.extend(["in", "python"])
print(words)
['this', 'is', 'a', 'list', 'in', 'python']
Please be aware that numbers.append would give us a very different result here, we would append a list of numbers in this case:
words = ["this", "is", "a", "list"]
words.append(["in", "python"])
print(words)
['this', 'is', 'a', 'list', ['in', 'python']]
print(len(words))
5
words = ["this", "is", "a", "list"]
words.sort()
print(words)
['a', 'is', 'list', 'this']
To find the position of an element:
print(words.index("list"))
2
print(words.index("python"))
--------------------------------------------------------------------------- ValueError Traceback (most recent call last) Cell In[10], line 1 ----> 1 print(words.index("python")) ValueError: 'python' is not in list
Element access, similar to strings:
Indexing starts with zero, upper limits are exclusive, negative indexes begin at the end
words = ["this", "is", "a", "list"]
print(words[0], words[-1])
this list
List slicing, similar to strings:
print(words[1:-1])
['is', 'a']
In contrast to Python strings, which are immutable ("const"), you can use index access as well as slicing for manipulation of a list
words[3] = "parrot"
print(words)
['this', 'is', 'a', 'parrot']
Deletion of parts of a list works like this:
del words[1:3]
print(words)
['this', 'parrot']
In the chapter about strings we did not mention two important string methods: str.split and str.join since we did not introduce lists back then.
The str.split method splits a string based on a given separator and returns a list of strings:
text = "this is some text, isn't it?"
print(text.split(" "))
print(text.split("is"))
['this', 'is', 'some', 'text,', "isn't", 'it?'] ['th', ' ', ' some text, ', "n't it?"]
Without arguments, str.split splits at white spaces (spaces, line breaks and tabs):
text = """this is some text,
isnt't it?
"""
print(text.split())
['this', 'is', 'some', 'text,', "isnt't", 'it?']
Comment: in case you want to split at different characters, e.g. at spaces and commas, the split function to the re module from the standard library can be used.
The inverse operation is called join: part.join(list_of_strings) will concatenate all strings from list_of_strings and insert the separator string part between them:
text = "this is some text, isn't it?"
parts = text.split()
print(parts)
back = " ".join(parts)
print(back)
['this', 'is', 'some', 'text,', "isn't", 'it?'] this is some text, isn't it?
print("".join(parts))
print(" - ".join(parts))
thisissometext,isn'tit? this - is - some - text, - isn't - it?
Comment: In case you want to concatenate many long strings, using "".join(...) can be significantly faster than using + !!!
tuples are "immutable" lists. Use round instead of square brackets:
a = (1, 3, 5)
print(a)
print(type(a))
(1, 3, 5) <class 'tuple'>
Rules of thumb:
structs in C/C++)For example like this:
person_1 = ("jesus", 2015) # name + age
person_2 = ("donald", 7)
people = [person_1, person_2]
Slicing / index access again:
tp = (1, 2, (1, 2), "")
print(tp[1:-1])
(2, (1, 2))
Empty tuple is (), for one element tuples use (x,) notation:
print((1,)) # prints tuple with one element
print((1)) # prints integer number 1
(1,) 1
The keyword in tests for membership:
print(2 in [0, 1, 2, 3])
True
print(2 in (0, 1, 2, 3))
True
For strings in tests for substrings:
print("ab" in "asdfabc")
True
Negation: you can either negate the result of the in expression:
print(not (2 in (1, 2, 3)))
False
or write in a more readable way:
print(2 not in (1, 2, 3))
False
lists are fundamental in Python and transforming lists is seen often Python programs.
Task: remove all odd numbers from a list of numbers.
One might be tempted to implement the functions as follows:
def remove_odd_numbers(li):
for number in li:
if number % 2 == 1:
li.remove(number)
return li
print(remove_odd_numbers([2, 1, 1, 1, 1, 4]))
[2, 1, 1, 4]
As you can see this did not work. The reason is that we changed the list while iterating over it.
Pattern:
In order to transform a list a into a list b it is common to start with b = [] and then incrementally update b based on the elements of a:
def remove_odd_numbers(li):
result = []
for number in li:
if number % 2 == 1:
continue
result.append(number)
return result
print(remove_odd_numbers([2, 1, 1, 1, 1, 4]))
[2, 4]
Use pen and paper and Python help function to determine is the value of a after executing:
a = [0, 1]
a.append(2)
a.append(a[:2])
a.insert(1, a[-1])
a.extend(a[1])
Write a function which flattens a nested list of lists (no deeper nesting), so flatten([[1], [2,3], [4, 5, 6]]) == [1, 2, 3, 4, 5, 6]).
Look up the definition of the fibionacci number sequence and write a function which takes an integer number n and computes a list of the first n fibionacci numbers (hint: start with [1, 1] and extend the list).
What is the output of the following program:
def f(x, a=[]):
a.append(x)
return len(a)
print(f(0))
print(f(1))
You might use additional print statements to inspect what's going on here.