Python For Quantum Mechanics#

Week 2: Compact Code#

from IPython.display import YouTubeVideo
YouTubeVideo('JBFc9V6BcNY',width=700, height=400)

Contents#

One-Line If and Else#

We can actually have an if/else condition in a single line. Lets say we have two variables a and b.

a=1
b=2

Now if we wanted to find out is a less than b we would write

if a < b:
    print('a is greater than b')
else:
    print('a is not greater than b')
a is greater than b

But we can acually write this as

print('a is greater than b' if a<b else 'a is not greater than b')
a is greater than b

We can even do this with more complicated conditional structures like

if a < b:
    c='less than'
elif a>b:
    c='greater than'
else:
    c='equal to'
    
print('a is', c, 'b')
a is less than b

This can be done by noting that elif is just an else and an if together.

print('a is', 'less than' if a<b else 'greater than' if a>b else 'equal to', 'b')
a is less than b

Comprehensions#

Comprehensions give a useful, compact syntax to create certain data structures from a given iterable object (list, tuple, range, etc…). Let’s say we want to create a list that contains the numbers from 0 to 10, inclusively, in order. Since we have loops and a way to append you might think a good solution is the following.

l=[]

for i in range(11):
    l.append(i)
    
print(l)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

This is better than not having a loop at all but is still a little clumbsy. We can in fact have a loop inside the assignment of the list. The following makes a list containing the values j (which will often depend on i) for each value i in the interable it

l = [j for i in iter].

For example

l = [i for i in range(11)]

print(l)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

We can also add in an if so only even numbers are in the list.

l = [i for i in range(11) if i%2==0]

print(l)
[0, 2, 4, 6, 8, 10]

Or prehaps more simply

l = [i*2 for i in range(6)]

print(l)
[0, 2, 4, 6, 8, 10]

We can even add in what we know about if and else!

words = ['zero','one','two','three','four','five','six','seven','eight','nine','ten']

l = [i if i%4==0 else words[i] for i in range(11) if i%2==0]

print(l)
[0, 'two', 4, 'six', 8, 'ten']

We can achieve the same thing with sets

s = {i%3 for i in range(30)}

print(s)
{0, 1, 2}

And even dictionaries

nums = [i for i in range(11)]

d = {word:num for word,num in zip(words,nums)}
print('d =',d)

print()

d_even = {word:num for word,num in d.items() if num%2==0}
print('d_even =',d_even)
d = {'zero': 0, 'one': 1, 'two': 2, 'three': 3, 'four': 4, 'five': 5, 'six': 6, 'seven': 7, 'eight': 8, 'nine': 9, 'ten': 10}

d_even = {'zero': 0, 'two': 2, 'four': 4, 'six': 6, 'eight': 8, 'ten': 10}

Generators#

Instead of an iterable containing all of it’s elements generators distinguish themselves by storing the information to generate elements. The function range() is in fact a generator. We can make our own generators with a similar sintax to what is used in comprehensions except now with ().

r=range(5,30,2)

gen = (i**2 for i in r)

for i in gen:
    print(i)
25
49
81
121
169
225
289
361
441
529
625
729
841