excess.org

Ian Ward

Consulting
Boxkite Inc.
Software
Urwid 2014-02-09 (1.2.0)
Speedometer 2011-12-08 (2.8)

Writing
Moving to Python 3
2011-02-17

Presentations
Urwid Applications
2012-11-14
Urwid Intro
2012-01-22
Unfortunate Python
2011-12-19
Django 1.1
2009-05-16
Article Tags

Home

Ian Ward's email:
first name at this domain

wardi on OFTC, freenode and github

Locations of visitors to this page

Python Container Literals

Literal Preview
Posted on 2012-11-01.

This post covers some basic Python syntax that tends to trip up people just starting with the language.

Literal tuple, list, dict and set definitions have some edge cases you need to be aware of when reading and writing Python code. Unfortunately some of these cases aren't consistent or obvious, but once you understand why they exist, they are easy to remember.

Without Literals

You can instantiate tuple, list, dict and set objects like any other by calling them like a function with an iterable with the contents (key/value pairs or keyword args for dict) they should have. This is a very useful way to convert one iterable or container to another.

/media/image/2012/11/literal1.png

Example 1: Check if our things already includes everything in other_things:

unique_things = set(things)
nothing_new = all(x in unique_things for x in other_things)

Example 2: Make a mutable version of a Python 3 range object:

numbers_remaining = list(range(10))
numbers_remaining.remove(5)
numbers_remaining.remove(1)

This is unsurprising code for people coming from another language. While you can instantiate empty versions of these containers by passing no arguments, Python programmers avoid calling tuple(), list() and dict() with no arguments, preferring the literal versions "()", "[]" and "{}".

With Literals

Python literal syntax is often a more concise way to define these containers and their contents in source code. With this brevity, however, we do run into some conflicts:

/media/image/2012/11/literal2.png

set and dict literals both use braces ({}). Python knows you want a dict or a set based on the presence of a colon (:) in each entry. Mixing set items and dict items in the same literal results in a SyntaxError.

There is no literal syntax for an empty set. "{}" was already taken to mean an empty dict since the language was first released. Similarly frozenset has no literal syntax at all.

Python always uses a comma to separate items in a container literal and always permits a trailing comma at the end of the items in the container. The optional comma at the end is a nice time saver - You can always add it in your code and never have to worry about cleaning up commas when adding or removing items in your code.

The one exception is that a comma is required at the end of a 1-item tuple. Why is that?

Parenthesis are already used for a number of things in python, including:

  • Precedence in expressions

    return (1 + a) * b
    
  • Splitting expressions across lines

    mouthful = ("I started saying one thing "
                "and continued on another line")
    

In Python "a" is the same as "(a)" which is the same as "(((((a)))))" because the meanings above depend on it, so we can't use parenthesis. Requiring a trailing comma for 1-item literal tuples, while a little unusual, is the simplest choice that keeps the rest of the language consistent.

Parenthesis are optional for tuples which encourages people to use them. tuples are efficient immutable containers - they consume little memory and encourage good programming habits. So that seems like a good language design choice.

return a, b
segment = value, run, repeat
for validate in check_size, check_spelling, check_caps:
    validate(value)

You must include parenthesis for tuples in cases such as:

  • empty tuples

    empty = ()
    
  • nested tuples

    display = 'light blue', ('bold', 'underline')
    
  • creating tuples in list comprehensions or generator expressions (this is a SyntaxError otherwise)

    swapped = [(y, x) for x, y in pairs]
    
  • tuples inside lists, dicts, sets or function calls

Tags: Software Python