Expressions, values, and statements

An expression is a piece of Python code that has a value. Values can be numbers (integer or floating-point), strings, lists, dictionaries, etc. If you type an expression in a Jupyter Notebook, there will be a line that starts with Out[X] and displays the value of the expression.

In [76]:
2+4
Out[76]:
6
In [77]:
(2+3)*7
Out[77]:
35

A statement does not return a value. It is usually there to get something done. The print statement has the effect of printing the value of the expression you pass to it. Notice that there is no Out[X] line here. For Python 2 users, notice that print now needs parentheses around the expression.

In [78]:
print(2+3)
5

Working with strings

Strings are one type of values in Python that is very important in CL. You can use lots of operations on strings, including concatenation, duplication, and indexing of substrings at particular positions or ranges.

In [79]:
"hello"
Out[79]:
'hello'
In [80]:
"hello " + "world"
Out[80]:
'hello world'
In [81]:
"hello" * 3
Out[81]:
'hellohellohello'
In [82]:
"hello"[1]
Out[82]:
'e'
In [83]:
"hello"[-1]
Out[83]:
'o'
In [7]:
"hello"[1:-1]
Out[7]:
'ell'
In [84]:
"hello"[1:]
Out[84]:
'ello'

Variables

Variables are names for places in your computer's memory. You can assign a value v to a variable; then the name of the variable becomes an expression whose value is v.

In Python, you can assign a new value to a variable even if it already has a value. Subsequent uses of the variable in an expression will yield the new value. The new value may have a different type than the old value (e.g. string vs. integer). You cannot use a variable before you have assigned a value to it.

In [85]:
x = 27
In [86]:
x
Out[86]:
27
In [87]:
x = 28
In [88]:
x
Out[88]:
28
In [89]:
x = "hallo"
In [90]:
x
Out[90]:
'hallo'
In [91]:
y
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-91-9063a9f0e032> in <module>
----> 1 y

NameError: name 'y' is not defined

Lists and how to modify them

Another important datatype is lists, i.e. sequences of arbitrary length. In Python, the different elements of the list can have different types. You can change the contents of a list by appending to its end or by overwriting a slice of the list with another list. You can iterate over the elements of a list, e.g. with a for loop.

In [153]:
L = [1,2,"hallo", None]
In [154]:
L
Out[154]:
[1, 2, 'hallo', None]
In [155]:
L.append(5)
In [157]:
L
Out[157]:
[1, 2, 'hallo', None, 5]
In [158]:
len(L)
Out[158]:
5
In [159]:
L[4]
Out[159]:
5
In [160]:
M = L[:5]
In [161]:
M
Out[161]:
[1, 2, 'hallo', None, 5]
In [162]:
M[0] = 27
In [163]:
M[2:5] = ["new element"]
In [164]:
M
Out[164]:
[27, 2, 'new element']
In [165]:
L
Out[165]:
[1, 2, 'hallo', None, 5]
In [166]:
for element in L:
    print(element)
1
2
hallo
None
5

Lists and sets

Lists are ordered sequences of values. To find out if some value appears in the list, Python must search for the value from left to right; this can be computationally expensive. By contrast, sets are unordered bags of values. Checking whether a value is in the set is dramatically faster than in a list (constant vs. linear runtime). Because sets are unordered, expressions like s[0] are meaningless. You can still iterate over the elements of a set, but the order in which they will be iterated is unspecified.

In [167]:
5 in L
Out[167]:
True
In [118]:
long_list = list(range(100000000))
In [119]:
len(long_list)
Out[119]:
100000000
In [120]:
-1 in long_list
Out[120]:
False
In [121]:
big_set = set(long_list)
In [122]:
len(big_set)
Out[122]:
100000000
In [123]:
-1 in big_set
Out[123]:
False
In [125]:
x = set([5, 1, 2, "hallo", 3, 2, 4, 5])
In [126]:
x
Out[126]:
{1, 2, 3, 4, 5, 'hallo'}
In [53]:
x[0]
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-53-2f755f117ac9> in <module>
----> 1 x[0]

TypeError: 'set' object does not support indexing
In [54]:
327 in x
Out[54]:
False
In [127]:
for element in x:
    print(element)
1
2
3
hallo
5
4

Dictionaries

You can put values into dictionaries under specific keys. Both keys and values can be of arbitrary types (but keys must be hashable, so e.g. you can't use lists as dictionary keys). You can add and overwrite entries in a dictionary.

In [168]:
d = { "foo": 2, "bar": -2}
In [171]:
d
Out[171]:
{'foo': 2, 'bar': -2, 'alksjdlaksjd': 19}
In [169]:
d["alksjdlaksjd"] = 19
In [170]:
d
Out[170]:
{'foo': 2, 'bar': -2, 'alksjdlaksjd': 19}
In [172]:
d["alksjdlaksjd"]
Out[172]:
19
In [173]:
d["foo"]
Out[173]:
2
In [134]:
"bar" in d
Out[134]:
True

Tuples

Lists, such as [1,2,3] are mutable: You can add, delete, and replace elements to an existing list object. A closely related datatype is the tuple (1,2,3), which behaves mostly like a list, but is immutable, i.e. its contents cannot be modified. Tuples can be useful to make sure you don't accidentally modify the elements. Also, keys in dictionaries must be immutable, so you can use tuples, but not list as keys in dictionaries.

In [147]:
a = (1,2,3)
In [174]:
a[0]
Out[174]:
1
In [149]:
a[0] = 5
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-149-33872b7931e7> in <module>
----> 1 a[0] = 5

TypeError: 'tuple' object does not support item assignment
In [175]:
d = {}
In [176]:
d[(1,2,3)] = 6
In [177]:
d
Out[177]:
{(1, 2, 3): 6}
In [178]:
d[ [1,2,3] ] = 7
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-178-458a2f66a643> in <module>
----> 1 d[ [1,2,3] ] = 7

TypeError: unhashable type: 'list'

To create a tuple with one element, use the syntax with the trailing comma below; simply enclosing an expression in brackets does not create a tuple, it simply brackets the expression.

In [150]:
(1,)
Out[150]:
(1,)
In [151]:
(1)
Out[151]:
1

You can assign a tuple (or list) of values to a tuple (or list) of variables. This assigns the first value to the first variable, the second to the second, and so on.

In [180]:
(a,b,c) = (1,2,3)
In [181]:
a
Out[181]:
1
In [182]:
b
Out[182]:
2

Functions

Define functions to package pieces of code that you want to use repeatedly. Functions can return values. They can return "multiple values" using comma notation; in reality, return a,b creates a tuple (a,b) and returns the tuple.

In [135]:
def add(x,y):
    return x+y+1
In [136]:
add(3, 5)
Out[136]:
9
In [137]:
def fibonacci(n):
    if n <= 1:
        return 1
    else:
        return fibonacci(n-1) + fibonacci(n-2)
In [138]:
fibonacci(1)
Out[138]:
1
In [139]:
fibonacci(2)
Out[139]:
2
In [140]:
def f(x):
    return x, x+1
In [141]:
one, two = f(7)
In [142]:
one
Out[142]:
7
In [143]:
two
Out[143]:
8

List comprehensions

List comprehensions are a succinct, readable, and efficient way of iterating over a list, set, or dictionary; computing a value for each element; and returning a list or dictionary of the resulting values. They are very nifty and powerful.

In [152]:
[x*x for x in [1,2,3,4]]
Out[152]:
[1, 4, 9, 16]
In [72]:
[fibonacci(x) for x in [0,1,2,3,4,5,6]]
Out[72]:
[1, 1, 2, 3, 5, 8, 13]
In [73]:
[fibonacci(x) for x in range(7)]
Out[73]:
[1, 1, 2, 3, 5, 8, 13]