Python for programmers (part 2)

This is part of my journey to learn Python (properly) by the reading the official language tour.

It's aimed for people already familiar with a C-style programming language. Think of it as a summary of the basic features and syntax of the language. This part is covering (5) Data Structures and (6) Modules.

Advanced lists

Methods like insert, remove, or sort only modify the list. They have no return value printed – they return the default None. This is a design principle for all mutable data structures in Python.

a_list = ['ab', 'cd', 'ef']

a_list.count('cd') # 1

a_list.index('ef') # 2

a_list.reverse() # [ef', 'cd', 'ab'] (None returned)

a_list.sort() # same list (already sorted, None returned)

a_list.pop() # 'ef'

List Comprehensions

Concise way to create lists. Consists of brackets containing an expression followed by a for clause, then zero or more for or if clauses.

squares = [x**2 for x in range(10)] 
# [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

[(x, y) for x in [1,2,3] for y in [3,1,4] if x != y]
# [(1, 3), (1, 4), (2, 3), (2, 1), (2, 4), (3, 1), (3, 4)]

Del

>>> a = [-1, 0, 1]
>>> del a[0]
# [0, 1]

Tuples

Immutable.
A number of values separated by commas.
Usually contain the same type of items.
Accessed via unpacking or indexing.

t = 12345, 54321

u = (12345, 54321), (1, 2, 3, 4, 5) # Nested tuple

empty = () # Empty tuple

singleton = 'hello', # Tuple with 1 element only

x, y = 12345, 54321 # Unpacking. x, y are assigned the respective value.

Sets

Unordered collection with no duplicate elements.

basket = {'apple', 'orange'} 

'orange' in basket # True (membership testing)

empty = set() # Not {} (this creates an empty dictionary)

Dictionaries

Indexed by keys, which can be any immutable type (e.g. strings and numbers, but not lists).

tel = {'jim': 4098, 'kate': 4139}
tel['hodor'] = 4127 # {'jim': 4098, 'kate': 4139, 'hodor': 4127}

del tel['kate'] # {'jim': 4098, 'hodor': 4127}

list(tel) # ['jim', 'hodor] # Keys in the insertion order

sorted(tel) # ['hodor', 'jim'] # Keys sorted

Looping Techniques

# Iterating throught a dictionary
knights = {'gallahad': 'the pure', 'robin': 'the brave'}
for key, value in knights.items():
    print(key, value)

# Iterating throught a list (along with the index)
words = ['tic', 'tac', 'toe']
for index, value in enumerate(words):
    print(index, value)

# Iterating through 2 lists at the same time
questions = ['name', 'quest', 'favorite color']
answers = ['lancelot', 'the holy grail', 'blue']
for question, answer in zip(questions, answers):
    print('What is your {0}?  It is {1}.'.format(q, a))

# Iterate a reverse list
for i in reversed([1, 10, 2]):
    print(i)

# Iterate a sorted list
for f in sorted(['pear', 'orange', 'banana']):
    print(f)

Modules

Module is a file containing Python definitions and statements. The file name is the module name with the suffix .py appended.

def greet():
    print('hello')
grt.py
import grt
grt.greet() # Will print 'hello'
grt.__name__ # Equals to 'grt'

# -- or ---

from grt as g
g.greet()

# -- or ---

from grt import greet
greet()

Search path

As expected, when importing a module Python will first look into the list of built-in modules -> directory containing the input script -> PYTHONPATH system variable -> installation-dependent default.

“Compiled” files

Python caches the compiled version of each module in the __pycache__ directory under the name module.version.pyc. "Compiled" modules are platform-independent. Only loading speed is faster from .pyc files, not execution time.

dir() function

Built-in function to find out which names a module defines.

import grt
dir(grt) # Equals ['__name__', 'greet']

Packages

Collection of modules.

pckg/                          Top-level package
      __init__.py              Initialize the sound package
      sub_pckg                 Subpackage
              __init__.py
              grt.py
              module_2.py
Example file structure

__init__.py is required to make Python treat the directory as a "package". Can just be empty, execute initialization code, or set the __all__ variable.

import pckg.sub_pckg.grt
pckg.sub_pckg.grt.greet()

# -- or ---

from pckg.sub_pckg import grt
grt.greet()

# -- or ---

from pckg.sub_pckg.grt import greet
greet()

What happens if import pckg.sub_pckg.*? Then the modules defined in __all__ variable from the sub_pckg 's __init__.py.

__all__ = ["grt", "module_2"]
init.py

Continue to part 3...