cafepy.com

Be Pythonic

This article is intended for new users of Python.

When going from one language to another, some things have to be unlearned (see Transfer of Learning). What you know from other languages may not be always useful in Python. This page contains some idioms used in Python that I particularly like, and I hope others find useful in their quest for Pythonicity.

You need counters rarely, and iterators only occasionally

Wrong:

i = 0
while i<10:
     do_something(i)
     i += 1

Pythonic:

for i in xrange(10):
    do_something(i)

The following example indexes a list.

Wrong:

i = 0
while i<len(lst):
    do_something(lst[i])
    i += 1

Pythonic:

for item in lst:
    do_something(item)

An iterator variable is useful when you want to maintain looping state between two 'runs':

itr_lst = iter(lst)

for item in itr_lst:
    do_something(item)
    if is_some_condition(item):
        break

for item in itr_lst:    # continues where previous loop left off
    do_something_else(item)

You may not need that for loop

Python provides many higher level facilities to operate on sequences, such as zip(), max(), min(), list comprehensions, generator expressions and so on. See Built-in Functions for these functions and more.

Keep data in tuples, lists and dictionaries, and operate on entire collections for that fuzzy Pythonic feeling. For example, here is some code that reads a CSV file (with first row being the field names), converts each line into a dictionary record, and calculates the sum on the 'quantity' column:

f = open('filename.csv')                    # f is an iterator
field_names = f.next().split(',')         # get the first item from the iterator using next()
records = [dict(zip(field_names, line.split(',')))  for line in f]  # this will pull remaining lines
print sum(int(record['quantity'])  for record in records)

Though a little naive (you should be using the csv module anyway, which is part of the Python Standard Library), this example demonstrates some useful features. Using zip() with dict() you can combine a tuple of field names with a tuple of values and make a dictionary - combine with list comprehensions you can do this to an entire list in one go.

Tuples are not read-only lists

Tuples usually indicate a heterogenous collection, for example (first_name, last_name) or (ip_address, port). Note that the type may be same (as in first_name and last_name may both be strings), but the real world meaning is usually different. You can think of a tuple as a row in a relational database - in fact the database row is even called a tuple in formal descriptions of the relational model. By contrast, a list of names is always a list, even though a particular function may not change it, that does not make it a tuple.

Tuple unpacking is a useful technique to extract values from a tuple. For example:

for (ip_address, port) in all_connections:
    if port<2000:
        print 'Connected to %s on %s' % (ip_address, port)

Reading this code tells you that all_connections is a list (or iterable) contaning tuples of the form (ip_address, port). This is much clearer than using for item in all_connections and then poking inside item using item[0] or similar techniques.

Unpacking is also useful while returning multiple values from a function:

name, ext = os.path.splitext(filename)    # split a file name into first part and extension

Classes are not for grouping utility functions

C# and Java can have code only within classes, and end up with many utility classes containing only static methods. A common example is a math functions such as sin(). In Python you just use a module with the top level functions.

Say no to getter and setter methods

Yes, encapsulation is important. No, getters and setters are not the only way to implement encapsulation. In Python, you can use a property to replace a member variable and completely change the implementation mechanism, with no change to any calling code.

Functions are objects

A function is a object that happens to be callable. This example sorts a list of dictionaries based on the value of 'price' key in the dictionaries:

#  define a function that returns useful data from within an object
def get_price(ob):
    return ob['price']

lst.sort(key=get_price)   # sort a list using the ['price'] value of objects in the list

In the above case, you can also avoid defining the simple get_price() function and instead just generate the function using operator.itemgetter('price').

You can also use sorted(lst, key=get_price) to return a new list instead of modifying the list in-place.

Related Links

This article originally appeared at http://shalabh.infogami.com/Be_Pythonic2

Comments

25 Oct, 2011
Anonymous*:

The last example is not pythonic. It should be

import operator L.sort(key = operator.itemgetter('price'))

25 Oct, 2011
Anonymous*:

The last example is not pythonic. It should be

L.sort(key=lambda x: x['price'])
26 Oct, 2011
Anonymous*:

@Anonymous (2)

Actually, try this:

from operator import itemgetter L.sort(key=itemgetter('price'))

14 Nov, 2011
Shalabh Chaturvedi:

Yes, itemgetter() can also be used in the last example to avoid defining the function. But the point I am making (specially for newcomers to Python not familiar with functions-as-objects) is that functions can be passed around easily. I don't want have too many concepts in one example to confuse the reader.

The same applies to labmda (also - it is not considered Python by a large portion of Python developers :).

25 Jul, 2014
Anastasiaetv*:

[HTML_REMOVED]クラークス ジャパン[HTML_REMOVED] [HTML_REMOVED]クラークス サンダル[HTML_REMOVED] [HTML_REMOVED]クラークス 靴[HTML_REMOVED] [HTML_REMOVED]クラークス[HTML_REMOVED] [HTML_REMOVED]クラークス 靴 レディース[HTML_REMOVED] [HTML_REMOVED]クラークス[HTML_REMOVED] [HTML_REMOVED]クラークス 靴 メンズ[HTML_REMOVED] [HTML_REMOVED]クラークス 靴 店舗[HTML_REMOVED] [HTML_REMOVED]クラークス メンズ[HTML_REMOVED] [HTML_REMOVED]クラークス レディース[HTML_REMOVED] [HTML_REMOVED]フォリフォリ ブレスレット[HTML_REMOVED] [HTML_REMOVED]フォリフォリ 時計[HTML_REMOVED] [HTML_REMOVED]フォリフォリ 店舗[HTML_REMOVED] [HTML_REMOVED]フォリフォリ 時計 レディース[HTML_REMOVED] [HTML_REMOVED]フォリフォリ 財布[HTML_REMOVED] [HTML_REMOVED]フォリフォリ ネックレス[HTML_REMOVED] [HTML_REMOVED]folli follie フォリフォリ[HTML_REMOVED] [HTML_REMOVED]フォリフォリ指輪[HTML_REMOVED] [HTML_REMOVED]フォリフォリ イヤリング[HTML_REMOVED] [HTML_REMOVED]フォリフォリ クラシック時計[HTML_REMOVED] [HTML_REMOVED]フォリフォリ クロノグラフ時計[HTML_REMOVED] [HTML_REMOVED]フォリフォリ ショルダーバッグ[HTML_REMOVED] [HTML_REMOVED]フォリフォリ ネックレス[HTML_REMOVED] [HTML_REMOVED]フォリフォリ ハンドバッグ[HTML_REMOVED] [HTML_REMOVED]フォリフォリ ブレスレット[HTML_REMOVED] [HTML_REMOVED]フォリフォリ ペンダント[HTML_REMOVED] [HTML_REMOVED]フォリフォリ 財布[HTML_REMOVED] [HTML_REMOVED]チャンルー ブレスレット[HTML_REMOVED] [HTML_REMOVED]チャンルー メンズ[HTML_REMOVED] [HTML_REMOVED]チャンルー ネックレス[HTML_REMOVED] [HTML_REMOVED]チャンルー[HTML_REMOVED] [HTML_REMOVED]チャンルー 2014[HTML_REMOVED] [HTML_REMOVED]チャンルー 店舗[HTML_REMOVED] [HTML_REMOVED]chan luu メンズ[HTML_REMOVED] [HTML_REMOVED]チャンルー メンズ ブレスレット[HTML_REMOVED] [HTML_REMOVED]チャンルー 2014[HTML_REMOVED] [HTML_REMOVED]チャンルー ネックレス[HTML_REMOVED] [HTML_REMOVED]チャンルー ピアス[HTML_REMOVED] [HTML_REMOVED]チャンルー ブレスレット[HTML_REMOVED] [HTML_REMOVED]チャンルー ラップブレスレット[HTML_REMOVED] [HTML_REMOVED]チャンルーメンズ[HTML_REMOVED] [HTML_REMOVED]サマンサタバサ[HTML_REMOVED] [HTML_REMOVED]サマンサタバサ バッグ[HTML_REMOVED] [HTML_REMOVED]サマンサタバサ 財布[HTML_REMOVED] [HTML_REMOVED]サマンサ[HTML_REMOVED] [HTML_REMOVED]サマンサタバサ アウトレット[HTML_REMOVED] [HTML_REMOVED]サマンサタバサ カゴバッグ[HTML_REMOVED] [HTML_REMOVED]サマンサタバサ ショルダーバッグ[HTML_REMOVED] [HTML_REMOVED]サマンサタバサ トートバッグ[HTML_REMOVED] [HTML_REMOVED]サマンサタバサ ハンドバッグ[HTML_REMOVED] [HTML_REMOVED]サマンサタバサ バッグ[HTML_REMOVED] [HTML_REMOVED]サマンサタバサ ボストンバッグ[HTML_REMOVED] [HTML_REMOVED]サマンサタバサ 時計[HTML_REMOVED] [HTML_REMOVED]サマンサタバサ 靴[HTML_REMOVED] [HTML_REMOVED]コーチ 時計[HTML_REMOVED] [HTML_REMOVED]Coach 靴[HTML_REMOVED] [HTML_REMOVED]Coach バッグ[HTML_REMOVED] [HTML_REMOVED]Coach 時計[HTML_REMOVED] [HTML_REMOVED]Coach 財布[HTML_REMOVED] [HTML_REMOVED]Coach 財布 メンズ[HTML_REMOVED] [HTML_REMOVED]Coach 財布 レディース[HTML_REMOVED] [HTML_REMOVED]コーチ アウトレット[HTML_REMOVED]

Post Comment
Sign In or provide:
Name*
Email*
Not disclosed
Human Test*
Comment*
Markdown formatting
powered by durusworks