In Python 2, use xrange instead of range.
Use reversed:
colors = ['red', 'green', 'blue'] for color in reversed(colors): print(color)
Use enumerate:
colors = ['red', 'green', 'blue'] for i, color in enumerate(colors): print("{} -> {}".format(i, color))
In Python 2, use izip from itertools:
from itertools import izip names = ['raymond', 'rachel', 'matthew'] colors = ['red', 'green', 'blue', 'yellow'] for name, color in izip(names,colors): print("{} -> {}".format(name, color))
Note that the lengths are different.
There is also zip (in Python 2), which actually creates the list, while izip is the iterator.
In Python 3 izip has been replaced by the built-in zip, and works as above.
Use sorted:
colors = ['red', 'green', 'blue'] for color in sorted(colors): print(color)
To sort by length:
colors = ['red', 'green', 'blue'] for color in sorted(colors, key=len): print(color)
Python's break only breaks out of one loop. To break out from two, make it a single loop. So:
for x in range(width): for y in range(height): <do something>
Create a range:
def range_2d(width, height): for x in range(width): for y in range(height): yield x, y
Then, you can do:
for x, y in range_2d(width, height): <do something>
Instead of:
for i in v: for j in w: <do something>
you can do
it = ( (i,j) for i in v for j in w ) # creates a GENERATOR for i,j in it: <do something>
d = {'matthew': 'blue', 'rachel': 'green', 'raymond': 'red'} for k in d: print k
If you want to change the dictionary while you loop, loop over d.keys():
for k in d.keys(): if k.startswith('r'): del d[k]
In Python 2, use the iterator itervalues:
for v in d.itervalues() <do stuff>
In Python 3 use values, which gives also a iterator. (values in Python 2 gives a list.)
In Python 2, use d.iteritems():
for key, value in d.iteritems() print("{} --> {}".format(key, value))
There is also d.items() which creates the list, while iteritems creates the iterator (much better).
In Python 3, you can just use items.
d = dict(izip(names, colors))
NOTE: izip has been replaced by zip in Python 3.
Use d.get. d.get(item,0) gives d[item] if possible and 0 otherwise.
d = {} v = [0,0,0,1,1,1,1,1,1,2,2,0,2,1] for x in v: d[x] = d.get(x,0) + 1
There is also d.setdefault(key, default_value), which also creates the d[key] if it does not exist already.
One can also use defaultdict(type), which creates an “empty” dictionary with values of type.
For instance, to create a dictionary grouping stings of names by length:
from collections import defaultdict d = defaultdict(list) for name in names: key = len(name) d[key].append(name)
If key does not exist, it creates it and sets the default value for list, which is an empty list. (And for int it is 0.)
v = [ 'a', 'b', 'c', 'd' ] w = [ 1, 2, 3, 4 ] my_dict = { letter : number for letter, number in zip(v,w) if number != 2 }
gives my_dict as { 'a' : 1, 'c' : 3, 'd' : 4 }.
(Use izip from itertools in Python 2.)
Use * for optional arguments with no default value.
def my_fct(x, *v): print('First value is {}'.format(x)) if v: # runs if v is not empty print('The other values are:') for value in v: print(value)
You can call it with my_fct(3), my_fct(3,4), my_fct(3,4,5), etc.
Also, if v = [1, 2], then my_fct(3,*v) is the same as my_fct(3,1,2).
In Python 3, if
def f(x, y, *, z=0, w=1): return x+y+z+w
you cannot call it as f(1,2,3,4), you must call it with f(1,2,x=3,w=4), i.e., the keyword arguments must be entered as keywords.
Instead of
def f(x,y): return x + y
do
f = lambda x, y: x + y
If v is a list and f is a function, then
fv = map(f,v)
applies f to entries of v. In Python 3 it is iterable. (To make a list, do fv = list(map(v)).) In Python 2 it gives a list.
Now if test is a conditional function,
testv = filter(test,v)
gives only the elements of v satisfying test. Similar to
testv = [ x in v if test(x) ]
but in Python 3 it gives an iterable, not a list.
You can use the else part of a for loop. So, instead of
def find(seq, target): found = False for i, value in enumerate(seq): if value == target: found = True break if not found: return -1 return i
do
def find(seq, target): for i, value in enumerate(seq): if value == target: found = True break else: return -1 return i
The else is like a nobreak: if the look finished normally, it skips the else part. If there is a break in the look, it runs the else part.
To save functions from recomputing the same value (with the expense of saving the computed values in memory) is to use@cache. So, instead of:
def my_fct(x, saved={}): if x in saved: return saved[x] <compute result> saved[x] = result return result
do
@cache def my_fact(x): <compute result> return result
Instead of:
f = open('data.txt') try: data = f.read() finally: f.close()
do
with open('data.txt') as f: data = f.read()
Instead of
sum([i**2 for i in xrange(10)])
do
sum(i**2 for i in xrange(10))
from collections import namedtuple Color = namedtuple('Color',['hue', 'saturation', 'luminosity']) p = Color(170, 0.1, 0.6) if p.saturation > 0.5: print('Bright!') if p.luminosity > 0.5: print('Light!')
See also: https://www.geeksforgeeks.org/namedtuple-in-python/
If you want to loop over the squares of integers from 1 to 1000, instead of creating the list
[ i**2 for i in range(1,1001)]
and looping, create the generator/iterator:
( i**2 for i in range(1,1001))
It's better in most cases to return generators/iterators instead of lists. So instead of:
def cubes(n): res = [] for i in range(n): res.append(i**3) return res
you can do
def cubes(n): for i in range(n): yield i**3
We can make it a list if we want to with list(cubes(10)), but we can use to iterate (only once per call), like:
for i in cubes(10): <do something with i>
Or, to extract the first three elements:
c = cubes(100000) next(c) next(c) next(c)
x = 1 if <condition> else 0
number = 100000000 print('The number is {:,}'.format(number))
a, b, c = (1, 2, 3, 4, 5)
gives an error. In Python 3 we can do
a, b, *c = (1, 2, 3, 4, 5)
gives an a = 1, b = 2, c = [3, 4, 5].
a, b, *_ = (1, 2, 3, 4, 5)
gives an a = 1 and b = 2.
a, b, *c, d = (1, 2, 3, 4, 5)
gives an a = 1, b = 2, c = [3, 4], and d = 5.
To hide the typed password:
from getpass import getpass username = input('Username: ') password = getpass('Password: ')
The following values are treated as False: “” (empty string), 0, 0.0, [] (empty list), () (empty tuple), {} (empty dictionary), False, None. If variable then is any of those, then
if variable: print('OK')
will not print OK, but will otherwise.
You cannot create and empty set wit my_set = {} as it creates an empty dictionary. So, you do it with my_set = set().
This also works for lists, tuples or dictionaries:
empty_list = [] empty_list = list() empty_tuple = () empty_tuple = tuple() empty_dict = {} empty_dict = dict()