Block B

Pooling and is

We have met the relational operators: < > <= >= != == . Today, we meet a new relational operator is.

Small integers are poooled. Run this fragment in Python (you can make a program or paste it into the prompt).


x = 5
y = 2 + 3
print(x==y)
print(x is y)

What happens here?


x = 5000
y = 2000 + 3000
print(x==y)
print(x is y)

Here is the example we did in class.


>>> x = 5
>>> y = 5
>>> x == y
True
>>> x is y
True
>>> x = 5000
>>> y = 5000
>>> x == y
True

The "small integers" -5 to 257 get preset location on the heap. This way, Python does not need to create them individually. This is done becasue they are used so often.

Moral of the Story Compare object values with ==, not is. You will see some cases where it is handy to use is Note that is is very fast because all it does is to compare to integers (memory addresses).

String are pooled, but it can be inconsistent


>>> x = "cow"
>>> y = "cow"
>>> x == y
True
>>> x is y
True

The cow's in the pool.

Compound Assignment Operators

We touched on these last time. If you have an infix binary operator op, then


x op= y

is the same as


x = x op (y)

Run this.


x = 5
x *= 2 + 1

Notice that the right-hand side is fully evaluated before the assignment is "seen."

This is the class examplle.


>>> x = 3 
>>> x += 5
>>> x *= 1 + 2
>>> x
24
>>> ##  x op=y  same as x = x op (y)

Here are some of the many infix binary opeators in Python: +, -, *, /, %, and //.

Let's look at += for strings.


>>> a = "abc"
>>> id(a)
4312163376
>>> a += "def"
>>> id(a)
4313114224

The original "abc" did not get touched. Python just created a new object for "abcdef" and made a point at it.

You will see this often. There is no ++ in Python.


>>> count = 0
>>> count += 1
>>> count
1
>>> count += 1
>>> count
2
>>> count += 1
>>> count
3

Sequence Types

Do you ever want to store related things in a single place so you can get at them easily?

You do this with your clothes in a dresser. Different drawers get used for different types of clothes (socks, shirts, underwear, etc.

picture of a highboy dresser

Python's sequence types provide one solution to this problem. Suppose you have a big file of data, such as this, the level of the water in Jordan Lake in feet above sea level in January of 2020.

214.6
214.7
217.0
218.5
218.5
218.4
218.3
218.1
217.9
217.8
217.5
217.2
216.9
216.8
216.7
216.7
216.9
217.2
217.2
217.3
217.3
217.1
217.0
216.7
216.5
216.3
216.2
216.2
216.3
216.3
216.3

Would you want to create a variable for each item in the list, or would you just like to store a list?

Copy this into a Python session.

The end of line comments allow this awkward thing to behave like a single line.

levels = [214.6, 214.7, 217.0, 218.5, 218.5, 218.4, 218.3, 218.1,# 
217.9, 217.8, 217.5, 217.2, 217.2, 216.9, 216.8, 216.7, 216.7,#
216.9, 217.2, 217.3, 217.3, 217.1, 217.0, 216.7, 216.5, 216.3,#
216.2, 216.2, 216.3, 216.3, 216.3]

This is a list. A list stores a sequence of Python objects. Another Python sequence type is a tuple. You will see that the primary difference between these types is that a list is mutable (our first mutable type) and that a tuple is not. At first, having two different types seems duplicative, but you will see that mutability has its dangers as well as its conveniences.


>>> levels = [214.6, 214.7, 217.0, 218.5, 218.5, 218.4, 218.3, 218.1,# 
... 217.9, 217.8, 217.5, 217.2, 217.2, 216.9, 216.8, 216.7, 216.7,#
... 216.9, 217.2, 217.3, 217.3, 217.1, 217.0, 216.7, 216.5, 216.3,#
... 216.2, 216.2, 216.3, 216.3, 216.3]
>>> levels
[214.6, 214.7, 217.0, 218.5, 218.5, 218.4, 218.3, 218.1, 217.9, 217.8, 217.5, 217.2, 217.2, 216.9, 216.8, 216.7, 216.7, 216.9, 217.2, 217.3, 217.3, 217.1, 217.0, 216.7, 216.5, 216.3, 216.2, 216.2, 216.3, 216.3, 216.3]

We shall compare them.

We can index into a list just as we can a string.


>>> levels[0]
214.6
>>> levels[1]
214.7
>>> s = "abcdef"
>>> s[0]
'a'
>>> s[1]
'b'

Our old friend len works here.


>>> len(s)
6
>>> len(levels)
31

Get with the in crowd!


>>> 214.6 in levels
True
>>> # in checks for membership of a object in a list using ==
>>> "a" in s
True
>>> "ac" in s
False
>>> #  ac is not a substring of s.
>>> [216.3, 216.3] in levels
False
>>> # no sublist checking

Strings as Sequences Strings are an oddity. They are "atomic" objects, but they can also be thought of as a character sequences. Certain sequence operations work on strings, a character at a time.

Python has elegant means for working with sequences that have lots of parallelism and economy of thought.

List Methods Lists are mutable so there is a lot you can do when changing their states. This can be convenient and dangerous.