# Numbers, Strings, and Lists¶

Python supports a number of built-in types and operations. This section covers the most common types, but information about additional types is available here.

## Basic numeric types¶

The basic data numeric types are similar to those found in other languages, including:

Integers (int)

In [1]:
i = 1
j = 219089
k = -21231

In [2]:
print(i, j, k)

1 219089 -21231


Floating point values (float)

In [3]:
a = 4.3
b = -5.2111222
c = 3.1e33

In [4]:
print(a, b, c)

4.3 -5.2111222 3.1e+33


Complex values (complex)

In [5]:
d = complex(4., -1.)

In [6]:
print(d)

(4-1j)


Manipulating these behaves the way you would expect, so an operation (+, -, *, **, etc.) on two values of the same type produces another value of the same type (with one, exception, /, see below), while an operation on two values with different types produces a value of the more 'advanced' type:

Adding two integers gives an integer:

In [7]:
1 + 3

Out[7]:
4

Multiplying two floats gives a float:

In [8]:
3. * 2.

Out[8]:
6.0

Subtracting two complex numbers gives a complex number:

In [9]:
complex(2., 4.) - complex(1., 6.)

Out[9]:
(1-2j)

Multiplying an integer with a float gives a float:

In [10]:
3 * 9.2

Out[10]:
27.599999999999998

Multiplying a float with a complex number gives a complex number:

In [11]:
2. * complex(-1., 3.)

Out[11]:
(-2+6j)

Multiplying an integer and a complex number gives a complex number:

In [12]:
8 * complex(-3.3, 1)

Out[12]:
(-26.4+8j)

However, the division of two integers gives a float:

In [13]:
3 / 2

Out[13]:
1.5

Note that in Python 2.x, this used to return 1 because it would round the solution to an integer. If you ever need to work with Python 2 code, the safest approach is to add the following line at the top of the script:

from __future__ import division



and the division will then behave like a Python 3 division. Note that in Python 3 you can also specifically request integer division:

In [14]:
3 // 2

Out[14]:
1

## Exercise 1¶

The operator for raising one value to the power of another is **. Try calculating $4^3$, $2+3.4^2$, and $(1 + i)^2$. What is the type of the output in each case, and does it make sense?

In [15]:
# enter your solution here


## Strings¶

Strings (str) are sequences of characters:

In [16]:
s = "Spam egg spam spam"


You can use either single quotes ('), double quotes ("), or triple quotes (''' or """) to enclose a string (the last one is used for multi-line strings). To include single or double quotes inside a string, you can either use the opposite quote to enclose the string:

In [17]:
"I'm"

Out[17]:
"I'm"
In [18]:
'"hello"'

Out[18]:
'"hello"'

or you can escape them:

In [19]:
'I\'m'

Out[19]:
"I'm"
In [20]:
"\"hello\""

Out[20]:
'"hello"'

You can access individual characters or chunks of characters using the item notation with square brackets[]:

In [21]:
s[5]

Out[21]:
'e'

Note that in Python, indexing is zero-based, which means that the first element in a list is zero:

In [22]:
s[0]

Out[22]:
'S'

Note that strings are immutable, that is you cannot change the value of certain characters without creating a new string:

In [23]:
s[5] = 'r'

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-23-e268c53f8105> in <module>()
----> 1 s[5] = 'r'

TypeError: 'str' object does not support item assignment

You can easily find the length of a string:

In [24]:
len(s)

Out[24]:
18

You can use the + operator to combine strings:

In [25]:
"hello," + " " + "world!"

Out[25]:
'hello, world!'

Finally, strings have many methods associated with them, here are a few examples:

In [26]:
s.upper()  # An uppercase version of the string

Out[26]:
'SPAM EGG SPAM SPAM'
In [27]:
s.index('egg')  # An integer giving the position of the sub-string

Out[27]:
5
In [28]:
s.split()  # A list of strings

Out[28]:
['Spam', 'egg', 'spam', 'spam']

## Lists¶

There are several kinds of ways of storing sequences in Python, the simplest being the list, which is simply a sequence of any Python object.

In [29]:
li = [4, 5.5, "spam"]


Accessing individual items is done like for strings

In [30]:
li[0]

Out[30]:
4
In [31]:
li[1]

Out[31]:
5.5
In [32]:
li[2]

Out[32]:
'spam'

Values in a list can be changed, and it is also possible to append or insert elements:

In [33]:
li[1] = -2.2

In [34]:
li

Out[34]:
[4, -2.2, 'spam']
In [35]:
li.append(-3)

In [36]:
li

Out[36]:
[4, -2.2, 'spam', -3]
In [37]:
li.insert(1, 3.14)

In [38]:
li

Out[38]:
[4, 3.14, -2.2, 'spam', -3]

Similarly to strings, you can find the length of a list (the number of elements) with the len function:

In [39]:
len([1,2,3,4,5])

Out[39]:
5

## Slicing¶

We already mentioned above that it is possible to access individual elements from a string or a list using the square bracket notation. You will also find this notation for other object types in Python, for example tuples or Numpy arrays, so it's worth spending a bit of time looking at this in more detail.

In addition to using positive integers, where 0 is the first item, it is possible to access list items with negative indices, which counts from the end: -1 is the last element, -2 is the second to last, etc:

In [40]:
li = [4, 67, 4, 2, 4, 6]

In [41]:
li[-1]

Out[41]:
6

You can also select slices from a list with the start:end:step syntax. Be aware that the last element is not included!

In [42]:
li[0:2]

Out[42]:
[4, 67]
In [43]:
li[:2]  # start defaults to zero

Out[43]:
[4, 67]
In [44]:
li[2:]  # end defaults to the last element

Out[44]:
[4, 2, 4, 6]
In [45]:
li[::2]  # specify a step size

Out[45]:
[4, 4, 4]

## Exercise 2¶

Given a string such as the one below, make a new string that does not contain the word egg:

In [46]:
a = "Hello, egg world!"



Try changing the string above to see if your solution works (you can assume that egg appears only once in the string).

## A note on Python objects (demo)¶

Most things in Python are objects. But what is an object?

Every constant, variable, or function in Python is actually a object with a type and associated attributes and methods. An attribute a property of the object that you get or set by giving the <object_name>.<attribute_name>, for example img.shape. A method is a function that the object provides, for example img.argmax(axis=0) or img.min().

Use tab completion in IPython to inspect objects and start to understand attributes and methods. To start off create a list of 4 numbers:

li = [3, 1, 2, 1]
li.<TAB>



This will show the available attributes and methods for the Python list li.

Using <TAB>-completion and help is a very efficient way to learn and later remember object methods!

In [2]: li.
li.append   li.copy     li.extend   li.insert   li.remove   li.sort
li.clear    li.count    li.index    li.pop      li.reverse



If you want to know what a function or method does, you can use a question mark ?:

In [9]: li.append?
Type:       builtin_function_or_method
String Form:<built-in method append of list object at 0x1027210e0>
Docstring:  L.append(object) -> None -- append object to end

## Exercise 3¶

In the following string, find out (with code) how many times the letter "A" appears.

In [47]:
s = "CAGTACCAAGTGAAAGAT"



Given two lists, try making a new list that contains the elements from both previous lists:

In [48]:
a = [1, 2, 3]
b = [4, 5, 6]



Note that there are several possible solutions!

## Dynamic typing¶

One final note on Python types - unlike many other programming languages where types have to be declared for variables, Python is dynamically typed which means that variables aren't assigned a specific type:

In [49]:
a = 1
type(a)

Out[49]:
int
In [50]:
a = 2.3
type(a)

Out[50]:
float
In [51]:
a = 'hello'
type(a)

Out[51]:
str

## Converting between types¶

There may be cases where you want to convert a string to a floating point value, and integer to a string, etc. For this, you can simply use the int(), float(), and str() functions:

In [52]:
int('1')

Out[52]:
1
In [53]:
float('4.31')

Out[53]:
4.31

For example:

In [54]:
int('5') + float('4.31')

Out[54]:
9.309999999999999

is different from:

In [55]:
'5' + '4.31'

Out[55]:
'54.31'

Similarly:

In [56]:
str(1)

Out[56]:
'1'
In [57]:
str(4.5521)

Out[57]:
'4.5521'
In [58]:
str(3) + str(4)

Out[58]:
'34'

Be aware of this for example when connecting strings with numbers, as you can only concatenate identical types this way:

In [59]:
'The value is ' + 3

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-59-98b8a5fb2a46> in <module>()
----> 1 'The value is ' + 3

TypeError: must be str, not int

In [60]:
'The value is ' + str(3)

Out[60]:
'The value is 3'

## Rounding floating point numbers to integers¶

By default, int will round floating point values down:

In [61]:
int(14.99)

Out[61]:
14

If you want to round to the nearest integer, you can instead use round or np.round:

In [62]:
round(14.9)

Out[62]:
15

In Python 2, round(14.9) returns 15.0 so to be safe, you should do:

In [63]:
int(round(14.9))

Out[63]:
15