Table Of Contents

Previous topic

Running Python code

Next topic

Assignment operator

This Page

Download this page as:

Python Built-in Types and Operations

Python supports a number of built-in types and operations. This tutorial 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):

    i = 1
    
  • Floating point values (float):

    f = 4.3
    
  • Complex values (complex):

    c = complex(4., -1.)
    

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, while an operation on two values with different types produces a value of the more ‘advanced’ type:

  • Adding two integers gives an integer:
In [1]: 1 + 3
 Out[1]: 4
  • Multiplying two floats gives a float:
In [2]: 3. * 2.
 Out[2]: 6.0
  • Subtracting two complex numbers gives a complex number:
In [3]: complex(2.,4.) - complex(1.,6.)
 Out[3]: (1-2j)
  • Multiplying an integer with a float gives a float:
In [4]: 3 * 9.2 # int * float = float
 Out[4]: 27.599999999999998
  • Multiplying a float with a complex number gives a complex number:
In [5]: 2. * complex(-1.,3.) # float * complex = complex
 Out[5]: (-2+6j)
  • Multiplying an integer and a complex number gives a complex number:
In [6]: 8 * complex(-3.3,1) # int * comples = comples
 Out[6]: (-26.4+8j)

However, there is one case where this happens but is not desirable, and that you should be aware of, which is the division of two integer numbers:

In [7]: 3 / 2
 Out[7]: 1

This is behavior is widely regarded as a design mistake and Python 3.x has been fixed to behave as you would expect (more on Python 3.x later). A way to prevent this is to cast at least one of the integers in the division to a float

In [8]: 3 / float(2)
 Out[8]: 1.5

or

In [9]: 3 / 2.
 Out[9]: 1.5

Solving the design mistake in Python 2.x (Click to Show/Hide)

At the top of a script or in the beginning of your session, you can import the future definition of the division operator. Note that / means normal division, while // means integer division. In Python 2.x, the two are equal for integers:

In [10]: 3/2
Out[10]: 1

In [11]: 3//2
Out[11]: 1

In [12]: from __future__ import division

In [13]: 3/2
Out[13]: 1.5

In [14]: 3//2
Out[14]: 1

Lists, tuples, and sets

There are two types of sequences that appear similar at first glance, both of which can contain inhomogeneous data types:

  • Lists (list):

    In [15]: l = [4, 5.5, "spam"]
    
    In [16]: l[0]
    Out[16]: 4
    
    In [17]: l[1]
    Out[17]: 5.5
    
    In [18]: l[2]
    Out[18]: 'spam'
    
  • Tuples (tuple):

    In [19]: t = (4, 5.5, "spam")
    
    In [20]: t[0]
    Out[20]: 4
    
    In [21]: t[1]
    Out[21]: 5.5
    
    In [22]: t[2]
    Out[22]: 'spam'
    

Warning

Indexing starts at 0 (as in C or IDL), not at 1 (as in Fortran or Matlab)!

We can obtain sublists of regularly-spaced elements in a list or tuple by ‘slicing:

In [23]: l = [1, 2, 3, 4, 5]

In [24]: l[2:4]
Out[24]: [3, 4]

Slicing syntax is l[start:stop:stride]. All the slicing parameters are optional:

In [25]: l[3:]
Out[25]: [4, 5]

In [26]: l[:3]
Out[26]: [1, 2, 3]

In [27]: l[::2]
Out[27]: [1, 3, 5]

Warning

Note that l[start:stop] contains the elements with indices i such that start<= i < stop (i ranging from start to stop-1). Therefore, l[start:stop] has (stop-start) elements.

We can also use negative numbers when slicing. These count from the end of the sequence:

In [28]: l[-1]
Out[28]: 5

In [29]: l[-2:]
Out[29]: [4, 5]

Using a negative step moves from higher to lower indices. For example, to reverse l:

In [30]: r = l[::-1]

In [31]: r
Out[31]: [5, 4, 3, 2, 1]

Lists are mutable objects and can be modified:

In [32]: l[0] = 28

In [33]: l
Out[33]: [28, 2, 3, 4, 5]

In [34]: l[2:4] = [3, 8]

In [35]: l
Out[35]: [28, 2, 3, 8, 5]

The elements of a list may have different types:

In [36]: l = [3, 2, 'hello']

In [37]: l
Out[37]: [3, 2, 'hello']

In [38]: l[1], l[2]
Out[38]: (2, 'hello')

Python offers a large number of functions to modify lists, or query them. Here are a few examples; for more details, see http://docs.python.org/tutorial/datastructures.html#more-on-lists

Add and remove elements:

In [39]: l = [1, 2, 3, 4, 5]

In [40]: l.append(6)

In [41]: l
Out[41]: [1, 2, 3, 4, 5, 6]

In [42]: l.pop()
Out[42]: 6

In [43]: l
Out[43]: [1, 2, 3, 4, 5]

In [44]: l.extend([6, 7]) # extend l, in-place

In [45]: l
Out[45]: [1, 2, 3, 4, 5, 6, 7]

Concatenate and repeat lists:

In [46]: r + l
Out[46]: [5, 4, 3, 2, 1, 1, 2, 3, 4, 5, 6, 7]

In [47]: 2 * r
Out[47]: [5, 4, 3, 2, 1, 5, 4, 3, 2, 1]

Sort r (in-place):

In [48]: r.sort()

In [49]: r
Out[49]: [1, 2, 3, 4, 5]

Note

Methods and Object-Oriented Programming

  • The notation r.method() (r.sort(), r.append(3), l.pop()) is an example of object-oriented programming (OOP). Being a list, the object r owns the method function that is called using the notation .. No further knowledge of OOP than understanding the notation . is necessary for going through this tutorial.

  • Most things in Python are objects! Every constant, variable, or function in Python is actually an 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> + dot + <attribute_name>, for example img.shape. A method is a function that the object provides, for example img.argmax(axis=0) or img.min().

  • In the IPython shell, we can take advantage of objects via tab completion:

    >>> r.<TAB>
    r.append   r.count    r.extend   r.index    r.insert   r.pop      r.remove   r.reverse  r.sort
    
  • Most methods are documented so that you can ask for help:

    >>> help(r.remove)
    Help on built-in function remove:
    
    remove(...)
        L.remove(value) -- remove first occurrence of value.
        Raises ValueError if the value is not present.
    

The difference between lists and tuples is that lists are mutable, and tuples are immutable:

In [50]: l = [1, 2, 3]

In [51]: l.append('egg')  # For a full list of methods, type l. then press TAB!

In [52]: l.insert(3, 'spam')

In [53]: l
Out[53]: [1, 2, 3, 'spam', 'egg']

In [54]: t = (1, 2, 3)

In [55]: t[0] = 3
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
/Users/naw/VM-Share/GREAT-ITN/GITN-Meetings/GITN-School-Alicante-Jun13/degroote-doc-v2/<ipython-input-55-d7bb3c58ee7f> in <module>()
----> 1 t[0] = 3

TypeError: 'tuple' object does not support item assignment

There are reasons why tuples are a useful feature (faster and hashable are the two main ones), but for now, it’s enough for you to know there is such a difference.

Sets (set) are a third type of sequence which you can make from a tuple or a list:

In [56]: set([1, 2, 3, 2, 'spam', 'egg', 'spam'])
Out[56]: set([1, 2, 3, 'egg', 'spam'])

Note that duplicate items have been removed. This is the mathematical definition of a set, i.e. a collection of distinct objects. The order of the objects is arbitrary (order is not preserved). Various operators can be used to represent set operations:

In [57]: set([1,2,3]) - set([3,4])
Out[57]: set([1, 2])

In [58]: set([1,2,3]) & set([3,4])
Out[58]: set([3])

In [59]: set([1,2,3]) | set([3,4])
Out[59]: set([1, 2, 3, 4])

If you want to test whether a single item is member of a very large collection of items, it can be faster to use a set rather than a list or tuple:

In [60]: 'a' in set(['a', 'b', 'c', 'd', 'e', 'f'])
Out[60]: True

For collections of numerical data that all have the same type, it is often more efficient to use the array type provided by the numpy module. A NumPy array is a chunk of memory containing fixed-sized items. With NumPy arrays, operations on elements can be faster because elements are regularly spaced in memory and more operations are perfomed through specialized C functions instead of Python loops.

Strings

Strings (str) will be familiar from other programming language:

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

You can use either single quotes ('), double quotes ("), or triple quotes (''') 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 [62]: "I'm"
Out[62]: "I'm"

In [63]: '"hello"'
Out[63]: '"hello"'

or you can escape them:

In [64]: 'I\'m'
Out[64]: "I'm"

In [65]: "\"hello\""
Out[65]: '"hello"'

Strings are sequences like lists. Hence they can be indexed and sliced, using the same syntax and rules.

Indexing:

In [66]: s = "hello"

In [67]: s[0]
Out[67]: 'h'

In [68]: s[1]
Out[68]: 'e'

In [69]: s[-1]
Out[69]: 'o'

(Remember that negative indices correspond to counting from the right end.)

Slicing:

In [70]: s = "hello, world!"

In [71]: s[3:6] # 3rd to 6th (excluded) elements: elements 3, 4, 5
Out[71]: 'lo,'

In [72]: s[2:10:2] # Syntax: a[start:stop:step]
Out[72]: 'lo o'

In [73]: s[::3] # every three characters, from beginning to end
Out[73]: 'hl r!'

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

In [74]: s[5] = 'r'
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
/Users/naw/VM-Share/GREAT-ITN/GITN-Meetings/GITN-School-Alicante-Jun13/degroote-doc-v2/<ipython-input-74-e268c53f8105> in <module>()
----> 1 s[5] = 'r'

TypeError: 'str' object does not support item assignment

In [75]: s.replace('l', 'z', 1)
Out[75]: 'hezlo, world!'

In [76]: s.replace('l', 'z')
Out[76]: 'hezzo, worzd!'

As for lists, and tuples, concatenation is done with +:

In [77]: "hello," + " " + "world!"
Out[77]: 'hello, world!'

Strings have many methods associated with them like .replace() used above. Here are a few more examples:

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

In [79]: s.upper() # An uppercase version of the string
Out[79]: 'SPAM EGG SPAM SPAM'

In [80]: s.index('egg') # An integer giving the position of the sub-string
Out[80]: 5

In [81]: s.split() # A list of strings
Out[81]: ['Spam', 'egg', 'spam', 'spam']

And finally, strings have a format method, which allows nice string formatting (see the official docs for a full overview).

In [82]: print('{:8.3f}'.format(3.14159265))
   3.142

In [83]: print('{:.10f}'.format(3.14159265))
3.1415926500

In [84]: print('{:.6e}'.format(3.14159265))
3.141593e+00

In [85]: print('{:04d}'.format(3))
0003

In [86]: print('{:g}'.format(3.14159265))
3.14159

In [87]: print('{:g}'.format(0))
0

In [88]: print('{:g}'.format(10000000000000000000000))
1e+22

Dictionaries

One of the remaining types are dictionaries (dict) which you can think of as look-up tables:

In [89]: d = {'name':'m31', 'ra':10.68, 'dec':41.27}

In [90]: d['name']
Out[90]: 'm31'

In [91]: d['flux'] = 4.5

In [92]: d
Out[92]: {'dec': 41.27, 'flux': 4.5, 'name': 'm31', 'ra': 10.68}

In [93]: list(d.keys())
Out[93]: ['flux', 'dec', 'name', 'ra']

In [94]: list(d.values())
Out[94]: [4.5, 41.27, 'm31', 10.68]

In [95]: 'ra' in d
Out[95]: True

See also

built-in_types Overview of all built-in types
numeric_types int, float, complex
sequence_types list, tuple, range
strings str
dictionaries dict
Copyright: Smithsonian Astrophysical Observatory under terms of CC Attribution 3.0 Creative Commons
 License