Python data types
Contents
Python data types¶
Python can be a little strange in providing lots of data types, dynamic type allocation, and some interconversion.
Numbers¶
Integers, Floating point numbers, and complex numbers are available automatically.
f = 1.0
i = 1
print (f, i)
print
print ("Value of f is {}, value of i is {}".format(f,i))
print
print ("Value of f is {:f}, value of i is {:f}".format(f,i))
## BUT !!
print ("Value of f is {:d}, value of i is {:f}".format(f,i))
c = 0.0 + 1.0j
print (c)
print ("Value of c is {:f}".format(c))
print ("Value of c**2 is {:f}".format(c**2))
Notes: The math
module needs to be imported before you can use it.
import math
math.sqrt(f)
math.sqrt(c)
math.sqrt(-1)
import cmath
print (cmath.sqrt(f))
print (cmath.sqrt(c))
print (cmath.sqrt(-1))
numbers as objects¶
Virtually everything in python is an object. This means that it is a thing that can have multiple copies made (all of which behave independently) and which knows how to do certain operations on itself.
For example, a floating point number knows certain things that it can do as well as simply “being” a number:
f
help(f)
print (f.is_integer() ) # Strange eh ?
print (f.conjugate())
print (c.conjugate())
print (f.__truediv__(2.0) ) # This looks odd, but it is the way that f / 2.0 is implemented underneath
1.0.__truediv__(2.0)
Strings¶
s = 'hello'
print (s[1] )
print (s[-1])
print (len(s) )
print (s + ' world')
ss = "\t\t HellO \n \t\t world\n \t\t !!!\n\n "
print (ss)
print (ss.partition(' '))
"Hello World".lower()
print (s[-1]," ", s[0:-1])
But one of the problems with strings as data structures is that they are immutable. To change anything, we need to make copies of the data
s[1] = 'a'
tuples and lists and sets¶
Tuples are bundles of data in a structured form but they are not vectors … and they are immutable
a = (1.0, 2.0, 0.0)
b = (3.0, 2.0, 4.0)
print (a[1])
print (a + b)
print (a-b)
print (a*b)
print( 2*a)
a[1] = 2
e = ('a', 'b', 1.0)
2 * e
Lists are more flexible than tuples, they can be assigned to, have items removed etc
l = [1.0, 2.0, 3.0]
ll = ['a', 'b', 'c']
lll = [1.0, 'a', (1, 2, 3), ['f', 'g', 'h']]
print (l)
print (ll)
print (l[2], ll[2])
print (2*l)
print (l+l)
print (lll)
print (lll[3], " -- sub item 3 --> ", lll[3][1])
2.0*l
l[2] = 2.99
l
l.append(3.0)
print (l)
ll += 'b'
print (ll)
ll.remove('b') # removes the first one !
print (ll)
l += [5.0]
print ("1 - ", l)
l.remove(5.0)
print ("2 - ", l)
l.remove(3.0)
print( "3 - ", l)
l.remove(4.0)
print ("4 - ", l)
Sets are special list-like collections of unique items. NOTE that the elements are not ordered (no such thing as s[1]
s = set([6, 5, 4, 3, 2, 1, 1, 1, 1])
print (s)
s.add(7)
print (s)
s.add(1)
s2 = set([5, 6, 7, 8, 9, 10, 11])
s.intersection(s2)
s.union(s2)
Dictionaries¶
These are very useful data collections where the information can be looked up by name instead of a numerical index. This will come in handy as a lightweight database and is commonly something we need to use when using modules to read in data.
d = { "item1": ['a', 'b', 'c'], "item2": ['c', 'd', 'e']}
print (d["item1"])
print (d["item1"][1])
d1 = {"Small Number":1.0, "Tiny Number":0.00000001, "Big Number": 100000000.0}
print (d1["Small Number"] + d1["Tiny Number"])
print (d1["Small Number"] + d1["Big Number"])
print (d1.keys())
for k in d1.keys():
print ("{:>15s}".format(k), " --> ", d1[k])
More useful is the fact that the dictionary can have as a key, anything that can be converted using the hash
function into a unique number. Strings, obviously, work well but anything immutable can be hashed:
def hashfn(item):
try:
h = hash(item)
print ("{}".format(str(item)), " --> ", h)
except:
print ("{}".format(item), " --> unhashable type {}".format((type(item))))
return
hashfn("abc")
hashfn("abd")
hashfn("alphabeta")
hashfn("abcdefghi")
hashfn(1.0)
hashfn(1.00000000000001)
hashfn(2.1)
hashfn(('a', 'b'))
hashfn((1.0, 2.0))
hashfn([1, 2, 3])
import math
hashfn(math.sin) # weird ones !!
Exercise: Build a reverse lookup table
Suppose you have this dictionary of phone numbers:
phone_book = { "Achibald": ("04", "1234 4321"),
"Barrington": ("08", "1111 4444"),
"Chaotica" : ("07", "5555 1234") }
Can you construct a reverse phone book to look up who is calling from their phone number ?
Solution: Here is a possible solution for the simple version of the problem but this could still use some error checking (if you type in a wrong number)
# Name: ( area code, number )
phone_book = { "Achibald": ("04", "1234 4321"),
"Barrington": ("08", "1111 4444"),
"Chaotica" : ("07", "5555 1234") }
newdict = {}
for key in phone_book:
newdict[phone_book[key]] = key
newdict
letters_and_numbers = [['a', 1], ['b', 2], ['c', 3]]
[i**2 for i in range(10)]
phone_book.items()
%%timeit
{val:key for key, val in phone_book.items()}
for letter, number in letters_and_numbers:
print(number * letter)
# Name: ( area code, number )
phone_book = { "Achibald": ("04", "1234 4321"),
"Barrington": ("08", "1111 4444"),
"Chaotica" : ("07", "5555 1234") }
reverse_phone_book = {}
%%timeit
for key in phone_book.keys():
reverse_phone_book[phone_book[key]] = key
print (reverse_phone_book[('07', '5555 1234')])