What Is New in Python 2.7
Python 2.7 was released on July 3, 2010, and became the final release of the Python 2.x series. It was the long-term support branch for Python 2, receiving security fixes until January 1, 2020. Python 2.7 backported many features from Python 3.1 to ease migration, including ordered dicts, set literals, dictionary and set comprehensions, and improved I/O. All Python 2 users should have migrated to Python 3 -- 2.7 is now end-of-life.
| Category | Change | Backported From |
|---|---|---|
| Standard Library | collections.OrderedDict |
Python 3.1 |
| Standard Library | collections.Counter |
Python 3.1 |
| Syntax | Set literals: {1, 2, 3} |
Python 3.x |
| Syntax | Dictionary comprehensions: {k: v for k, v in items} |
Python 3.x |
| Syntax | Set comprehensions: {x for x in iterable} |
Python 3.x |
| Standard Library | argparse module |
Python 3.2 |
| Standard Library | unittest improvements -- test discovery, assertIn, skip decorators |
Python 3.2 |
| Numerics | Smarter float repr -- repr(0.1) now returns '0.1' |
Python 3.1 |
| Numerics | Comma separator in format specification ("{:,}".format(n)) |
Python 3.1 |
| Standard Library | Improved multiprocessing, logging, ssl modules |
-- |
| End of Life | EOL: January 1, 2020. No further fixes of any kind. | PEP 373 |
What Was Backported Into Python 2.7?
collections.OrderedDict and Counter
OrderedDict ensures dictionary iteration follows insertion order -- a guarantee that plain dict did not make in Python 2. Counter is a specialized dict for counting hashable objects, with convenience methods like most_common().
from collections import Counter, OrderedDict
word_counts = Counter("abracadabra".split())
# Not useful for single chars -- better example:
words = "the quick brown fox jumped over the lazy dog".split()
c = Counter(words)
c.most_common(3) # [('the', 2), ('quick', 1), ...]
od = OrderedDict([("a", 1), ("b", 2), ("c", 3)])
list(od.keys()) # ["a", "b", "c"] -- guaranteed
Set Literals and Comprehensions
Python 2.7 backported the curly-brace set literal syntax from Python 3. Dict comprehensions and set comprehensions also came along. Note: {} alone is still an empty dict -- use set() for an empty set.
primes = {2, 3, 5, 7, 11, 13} # set literal
evens = {x for x in range(20) if x % 2 == 0} # set comprehension
inv = {v: k for k, v in mapping.items()} # dict comprehension
Improved float repr
Python 2.7 adopted the same David Gay dtoa algorithm used in Python 3.1. repr(0.1) now gives '0.1' instead of the confusing '0.10000000000000001'. The underlying float value is unchanged -- only the representation is shorter and round-trip safe.
Python 2.7 End-of-Life
Python 2.7 reached end-of-life on January 1, 2020. No further security patches, bug fixes, or CVE responses will be issued. The PSF officially stopped maintaining it. If you are still running Python 2.7 in any production system, upgrading to Python 3.8+ is urgent and overdue. Tools like 2to3, futurize, and modernize exist to assist migration.
FAQ
Can Python 2.7 code run on Python 3 without changes?
Almost never, for non-trivial code. The string/bytes split, print as a function, integer division, and many renamed modules are all breaking changes. The 2to3 script handles common mechanical conversions, but logic that relies on str being bytes or implicit ASCII encoding needs manual review.
What is the recommended upgrade path from Python 2.7?
Target Python 3.8 or newer -- it is the earliest version still receiving security support as of 2024. If you need intermediate compatibility, upgrade to Python 2.7 + the future or six library first to write Python 3-compatible code that still runs on 2.7, then cut over to 3.x when ready.
Were any security fixes released for Python 2.7 after January 2020?
The PSF stopped. Some Linux distributions (notably RHEL 7) continued to backport security patches into their bundled Python 2.7 under their own support terms. But upstream CPython received no further patches.
Is there any valid reason to keep Python 2.7 code?
Very rarely: legacy systems where migration cost is prohibitively high, or embedded systems with a frozen toolchain. In all other cases, there is no justification -- Python 3 has been production-stable and feature-superior since at least 3.6.
What is the key difference between Counter.most_common() and sorting by value?
most_common(n) uses a heap internally, giving O(n log k) complexity where k is the number of results needed. Sorting the full counter gives O(m log m) where m is the total number of unique elements. For small n relative to m, most_common(n) is faster.