Differences from the builtins

The transient types behave like list, set, and dict, and the persistent types behave like them wherever immutability allows. This page lists the differences.

Persistent types return new collections

Methods that change a builtin collection instead return a new collection:

Builtin

Persistent

l.append(x)

p = p.append(x)

l[i] = x

p = p.set(i, x)

del l[i]

p = p.delete(i) or p = p.drop(i)

x = l.pop()

(x, p) = p.pop()

l.sort()

p = p.sort()

s.add(x)

p = p.add(x)

s.discard(x)

p = p.discard(x)

x = s.pop()

(x, p) = p.pop()

d[k] = v

p = p.set(k, v)

del d[k]

p = p.delete(k) or p = p.drop(k)

v = d.pop(k)

(v, p) = p.pop(k)

(k, v) = d.popitem()

((k, v), p) = p.popitem()

d.update(other)

p = p.update(other) or p = p | other

v = d.setdefault(k, x)

p = p.setdefault(k, x) (returns the mapping)

l.clear()

p = p.clear() (the empty collection)

Persistent collections also have methods that the builtins lack: plist.prepend, pset.addall, pset.discardall, pset.removeall, pdict.setall, pdict.dropall, and pdict.deleteall. The transient types have tlist.prepend, tset.addall, tset.discardall, and tset.removeall.

drop and delete differ only when the key (or index) isn’t present: delete raises KeyError (or IndexError), and drop returns the collection unchanged, or raises if its error argument is true.

The persistent types have no in-place operators; p += x rebinds p to p + x.

Hashing and equality

  • Persistent collections are hashable when their elements are. A pset hashes like an equal frozenset. Transient collections, like list, set, and dict, aren’t hashable.

  • A plist or tlist equals a list with equal elements, and never equals a tuple (as with list). A pset or tset equals an equal set or frozenset, and a pdict or tdict equals an equal dict.

  • list + plist returns a plist (and list + tlist a tlist), since list leaves the operation to the other operand. For the same reason, dict | pdict returns a pdict and set | pset returns a pset.

  • A persistent collection isn’t an instance of the corresponding builtin (a pset isn’t a frozenset), but every type is registered with the matching abstract base class in collections.abc (Sequence, Set, Mapping, or their mutable versions) and with those in pcollections.abc.

Construction

  • pdict.empty, plist.empty, and pset.empty are the empty collections. For the transient types, empty() is a class method that returns a new empty collection.

  • The constructors accept the same arguments as those of the builtins. plist(p), pset(p), and pdict(p) return p itself when it is already of that type.

Order

pdict, tdict, pset, and tset iterate in the order in which their elements were added. (set and frozenset don’t guarantee an order.)

popitem() (on pdict and tdict) removes the last item, the one most recently added, as dict.popitem() does. pop() (on pset and tset) also removes the last element, where set.pop() removes an arbitrary one.

Printing

Persistent collections print with | inside their brackets ([|1, 2|], {|1, 2|}, {|'a': 1|}), and transient collections with < and > ([<1, 2>]).

Performance

Lookups and modifications take time that grows at most logarithmically with the size of the collection, and transient() and persistent() take constant time. The exceptions are in the list types: inserting or deleting an element in the middle of a plist or tlist, and slice assignment and deletion on a tlist, take time proportional to the length of the list. (Appending, prepending, and removing the first or last element don’t.)

The builtins are faster for most single operations. The persistent types are much faster than copying a builtin collection to make a changed version of it.

Transients and threads

A modification of a transient collection that overlaps another modification of the same collection, from another thread or from code that runs during the modification, raises RuntimeError instead of corrupting the collection, and so does a read made while a modification is in progress. See Threads.

Subclasses

Methods that return new collections return instances of the subclass (where list, set, and dict return instances of the builtin), and instances of persistent subclasses can’t have attributes set. See Subclassing.