Effective Python (1): Pythonic Thinking

Item 1: Know Which Version of Python You're Using

  • Two mayor versions of Python in active use: Python 2 and Python 3;
  • Multiple popular runtime for Python: CPython, Jython, IronPython, PyPy, etc;
  • Prefer Python3 because that is the primary focus of the Python community.

Item 2: Follow the PEP 8 Style Guide

  • Always follow the PEP 8 style guide when writing python codes.

Item 3: Know the Differences Between bytes, str, and unicode

  • In python 3, bytes contains sequences of 8-bit values, str contains sequences of Unicode characters. bytes and str instances can't be used together with operators (like > or +);
  • In python 2, str contains sequences of 8-bit values, unicode contains sequences of Unicode characters. str  and unicode  instances can be used together with operators if the str only contains 7-bit ASCII characters;
  • Use helper functions to ensure that the inputs you operate on are the type of character sequence you expect;
  • - If you want to read or write binary data to/from a file, always open the file using a binary mode(like ‘rb’ or ‘wb’).

The core of your program should use Unicode character types

  • str in python 3
  • unicode in python 2

Helper functions:

#! Python 3
# Takes a str or bytes and always returns a str
def to_str(bytes_or_str):
    if isinstance(bytes_or_str, bytes):
        value = bytes_or_str.decode('utf-8')
    else:
        value = bytes_or_str

    return value

# Takes a str or bytes and always returns a bytes
def to_bytes(bytes_or_str):
    if isinstance(bytes_or_str, str):
        value = bytes_or_str.encode('utf-8')
    else:
        value = bytes_or_str

    return value
#! Python 2
# Takes a str or unicode and always returns a unicode
def to_unicode(unicode_or_str):
    if isinstance(unicode_or_str, str):
        value = unicode_or_str.decode('utf-8')
    else:
        value = unicode_or_str

    return value

# Takes a str or unicode and always returns a str
def to_str(unicode_or_str):
    if isinstance(unicode_or_str, unicode):
        value = unicode_or_str.encode('utf-8')
    else:
        value = unicode_or_str

    return value

Item 4: Write Helper Functions Instead of Complex Expressions

Pass

Item 5: Know How to Slice Sequences

  • Avoid being verbose: Don’t supply 0 for the start index or the length of the sequence for the end index;
  • Slicing is forgiving of start or end indexes that are out of bounds, making it easy to express slices on the front or back boundaries of a sequence(like a[:20] or a a[-20:]);
  • Assigning to a list slice will replace that range in the original sequence with what’s referenced even if their lengths are different.

Item 6: Avoid Using start, end, and stride in a Single Slice

  • Prefer using positive stride values in slices without start or end indexes. Avoid negative stride values if possible.
  • Consider doing two assignments(one to slice, another to stride) or using islice from the itertools built-in module.

Item 7: Use List Comprehensions Instead of map and filter

  • List comprehensions are clearer than the map and filter build-in functions because they don’t require extra lambda expressions.
  • List comprehensions allow you to easily skip items from the input list, a behavior map doesn’t support without help from filter.
  • Dictionaries and sets also support comprehension expressions.

Item 8: Avoid More Than Two Expressions in List Comprehensions

Pass

Item 9: Consider Generator Expressions for Large Comprehensions

Pass

Item 10: Prefer enumerate Over range

Code example

flavor_list = ['vanilla', 'chocolate', 'pecan', 'strawberry']

for i, flavor in enumerate(flavor_list, 1):
    print('%d: %s' % (i, flavor))
  • enumerate provides concise syntax for looping over an iterator and getting the index of each item from the iterator as you go;
  • You can supply a second parameter to enumerate to specify the number from which to begin counting (zero is the default).

Item 11: Use zip to Process Iterators in Parallel

  • In python 3, zip is a lazy generator that produces tuples. While in python 2, zip returns the full result as a list of tuples;
  • zip truncates its output silently if you supply it with iterators of different lengths.

Item 12: Avoid else Blocks After for and while Loops

  • The else block after a loop only runs if the loop body did not encounter a break statement.

Item 13: Take Advantage of Each Block in try/except/else/finally

  • The else block helps you minimize the amount of code in try blocks and visually distinguish the success case from the try/except blocks.
  • An else block can be used to perform additional actions after a successful try block but before common cleanup in a finally block.
posted @ 2016-01-24 22:01  luckysimple  阅读(190)  评论(0编辑  收藏  举报