What Is New in Python 2.0
Python 2.0 was the first release under the newly formed BeOpen Python Labs, and then transferred to the Python Software Foundation. It introduced list comprehensions, augmented assignment operators (+=, -=, etc.), Unicode strings as a first-class type, garbage collection for cyclic references, and the zip() built-in. Python 2.0 also adopted a community-driven development model with Python Enhancement Proposals (PEPs).
| Category | Change | Notes |
|---|---|---|
| New Syntax | List comprehensions: [expr for x in iterable if cond] |
PEP 202 |
| New Syntax | Augmented assignment: +=, -=, *=, /=, etc. |
PEP 203 |
| Strings | Unicode strings as a first-class type (u"hello") |
PEP 100 |
| Memory | Cycle-detecting garbage collector for reference cycles | -- |
| Builtins | zip() built-in function |
-- |
| Builtins | map() with None as function: tuple-zipping behavior |
-- |
| Standard Library | distutils -- package distribution tools |
-- |
| Standard Library | xml package -- SAX and miniDOM parsers |
-- |
| Process | Python Enhancement Proposals (PEPs) as formal process for language changes | PEP 1 |
Key Features in Python 2.0
List Comprehensions (PEP 202)
List comprehensions provided a concise and readable way to build lists from iterables, replacing the map()/filter() combination or manual loop-and-append patterns. They borrowed syntax from Haskell's list comprehensions.
# Before list comprehensions
squares = []
for x in range(10):
squares.append(x**2)
# With list comprehensions (Python 2.0+)
squares = [x**2 for x in range(10)]
evens = [x for x in range(20) if x % 2 == 0]
# Nested comprehensions
pairs = [(x, y) for x in range(3) for y in range(3) if x != y]
Augmented Assignment (PEP 203)
Augmented assignment operators (+=, -=, *=, /=, **=, %=, &=, |=, ^=, <<=, >>=, //=) allow in-place modification and call the corresponding __iadd__, __isub__, etc. methods. For mutable objects like lists, a += b modifies a in place rather than creating a new object.
count = 0
count += 10 # Same as count = count + 10
items = [1, 2, 3]
items += [4, 5] # Extends in place via __iadd__ -- same list object
Unicode Strings (PEP 100)
Python 2.0 introduced Unicode strings as a separate type (u"text") alongside the existing byte-string str. The two types could be mixed in some operations, leading to encoding errors at runtime. This dual-string system was one of the most criticized aspects of Python 2 -- Python 3 fixed it by making all strings Unicode and requiring explicit bytes for binary data.
Cycle-Detecting Garbage Collector
Python's primary memory management is reference counting. But reference counting cannot handle cycles -- two objects referencing each other with no other references both have a count of 1 and are never freed. Python 2.0 added an optional cycle-detecting GC (enabled by default) that periodically finds and frees such cycles. The gc module exposes the collector for manual triggering and diagnostics.
The Beginning of the PEP Process
Python 2.0 was the first release developed under the PEP (Python Enhancement Proposal) process, inspired by the IETF's RFC system. PEPs became the formal channel for proposing, discussing, and documenting language changes. All major features since Python 2.0 have a corresponding PEP number. This shift also marked Python moving from Guido van Rossum developing changes largely alone to a community-reviewed process.
FAQ
Why were list comprehensions considered a significant addition in 2.0?
Before them, generating a list required either a for-loop with append or map()/filter() with lambdas -- both more verbose. List comprehensions made common data transformation patterns one-liners, and they execute faster than equivalent loop-based code because the list-building is done entirely at the C level without repeated Python attribute lookups.
How do augmented assignments interact with immutable objects?
For immutable objects like integers and strings, a += b is equivalent to a = a + b -- a new object is created. For mutable objects like lists, a += b calls a.__iadd__(b) which modifies a in place. This distinction matters when a is a list element or function argument -- in-place extension changes the underlying object, which may be visible to other references.
What is the gc module used for in practice?
Mostly diagnostics: finding uncollectable objects, measuring collection counts, and diagnosing memory leaks involving cycles. gc.collect() triggers a full collection manually -- useful before taking a memory snapshot. gc.get_referrers(obj) finds all objects that hold a reference to obj, which helps trace unexpected references keeping objects alive.
When did the PSF take stewardship of Python from BeOpen?
Python 2.0 was released under BeOpen Python Labs in October 2000. Shortly after, the intellectual property was transferred to the Python Software Foundation (PSF), which was incorporated in 2001. All Python versions from 2.1 onward have been developed and released under the PSF.
Were there Python versions before 2.0 that are worth knowing about?
Python 1.5.2 (1999) was the dominant version for much of the late 1990s and was extremely widely deployed. Python 1.6 was a brief intermediate release. For historical context, Python 1.x code looks similar to modern Python in structure but lacks most of the features that make Python 2.x and 3.x powerful. No practical development targets Python 1.x.