From Raymond Hettinger's Transforming Code into Beautiful, Idiomatic Python
Whenever you're manipulating indices directly, you're probably doing it wrong
foriin [0, 1, 2, 3, 4, 5]:
printi**2# the python way# range() takes a small amount of memory because it calculates individual items as neededforiinrange(6):
printi**2colors= ['red', 'green', 'blue', 'yellow']
foriinrange(len(colors)):
printcolors[i]
# the python wayforcolorincolors:
printcolorcolors= ['red', 'green', 'blue', 'yellow']
foriinrange(len(colors)-1, -1, -1):
printcolors[i]
# the python wayforcolorinreversed(colors):
printcolorcolors= ['red', 'green', 'blue', 'yellow']
foriinrange(len(colors)):
printi, '-->', colors[i]
# the python wayfori, colorinenumerate(colors):
printi, '-->', colorzip(*iterables): Makes an iterator that aggregates elements from each of the iterables.
names= ['raymond', 'rachel', 'matthew']
colors= ['red', 'green', 'blue', 'yellow']
n=min(len(names), len(colors))
foriinrange(n):
printnames[i], '-->', colors[i]
# the python wayforname, colorinzip(name, colors):
printname, '-->', coloritertools.product(*iterables, repeat=1): Cartesian product of input iterables.
names= ['raymond', 'rachel', 'matthew']
colors= ['red', 'green', 'blue', 'yellow']
fornameinnames:
forcolorincolors:
print(name, color)
# the python wayfromitertoolsimportproductproducts=product(names, colors)
forname, colorinproducts:
... print(name, color)sorted(iterable[, key][, reverse])
colors= ['red', 'green', 'blue', 'yellow']
forcolorinsorted(colors):
printcolor# reverse orderforcolorinsorted(colors, reverse=True):
printcolor# custom orderforcolorinsorted(colors, key=len):
printcolorAs soon as you've made something iterable, it works with all of the Python toolkit
iter(object[, sentinel])functools.partial(func, *args, **keywords)
# sentinel value the traditional wayblocks= []
whileTrue:
block=f.read(32)
ifblock='':
breakblocks.append(block)
# the second argument of the iter function is a sentinel value# in order to make it work, the first function has to be a function with no arguments, hence the partialblocks= []
forblockiniter(partial(f.read, 32), ''):
blocks.append(block)The for loop else should have been called nobreak
deffind(seq, target):
found=Falsefori, valueinenumerate(seq):
ifvalue==tgt:
found=Truebreakifnotfound:
return-1returnideffind(seq, target):
fori, valueinenumerate(seq):
ifvalue==tgt:
breakelse:
return-1returnid= {'matthew': 'blue', 'rachel': 'green', 'raymond': 'red'}
forkind:
printkforkind.keys():
ifk.startswith('r'):
deld[k]d= {'matthew': 'blue', 'rachel': 'green', 'raymond': 'red'}
forkind:
printk, '-->', d[k]
# the python wayfork, vind.items():
printk, '-->', vnames= ['raymond', 'rachel', 'matthew']
colors= ['red', 'green', 'blue', 'yellow']
d=dict(zip(names, colors))class collections.defaultdict([default_factory[, ...]])
colors= ['red', 'green', 'red', 'blue', 'green', 'red']
d= {}
forcolorincolors:
ifcolornotind:
d[color] =0d[color] +=1d= {}
forcolorincolors:
d[color] =d.get(color, 0) +1# the python wayd=defaultdict(int)
forcolorincolors:
d[color] +=1names= ['raymond', 'rachel', 'matthew', 'roger', 'betty', 'melissa', 'judith', 'charlie']
d= {}
fornameinnames:
key=len(name)
ifkeynotind:
d[key] = []
d[key].append(name)
d= {}
fornameinnames:
key=len(name)
d.setdefault(key, []).append(name)
# the python wayd=defaultdict(list)
fornameinnames:
key=len(name)
d[key].append(name)popitem() is atomic so it can be used bewteen threads
d= {'matthew': 'blue', 'rachel': 'green', 'raymond': 'red'}
whiled:
key, value=d.popitem()
printkey, '-->', valuedefaults= {'color': 'red', 'parser': 'guest'}
parser=argparse.ArgumentParser()
parser.add_argument('-u', '--user')
parser.add_argument('-c', '--color')
namespace=parser.parse_args([])
command_line_args= {k: vfork, vinvars(namespace).items() ifv}
d=default.copy()
d.update(os.environ)
d.update(command_line_args)
# the python wayd=ChainMap(command_line_args, os.environ, defaults)twitter_search('@obama', False, 20, True)
# the python waytwitter_search('@obama', retweets=False, numtweets=20, popular=True)doctest.testmod()
# output: (0, 4)TestResults=namedtuple('TestResults', ['failed', 'attempted'])
doctest.testmod()
# output: TestResults(failed=0, attempted=4)p='Raymond', 'Hettinger', 0x30, 'python@example.com'fname=p[0]
lname=p[1]
age=p[2]
email=p[3]
# the python wayfname, lname, age, email=pdeffibonacci(n):
x=0y=1foriinrange(n):
printxt=yy=x+yx=t# the python waydeffibonnaci(n):
x, y=0, 1foriinrange(n):
printxx, y=y, x+ynames= ['raymond', 'rachel', 'matthew', 'roger', 'betty', 'melissa', 'judith', 'charlie']
s=names[0]
fornameinname[1:]:
s+=', '+nameprints# the python way', '.join(names)names= ['raymond', 'rachel', 'matthew', 'roger', 'betty', 'melissa', 'judith', 'charlie']
# whenever you use this you should be using a deque insteaddelnames[0]
names.pop(0)
names.insert(0, 'mark')
names=deque(['raymond', 'rachel', 'matthew', 'roger', 'betty', 'melissa', 'judith', 'charlie'])
delnames[0]
names.popleft()
names.appendleft('mark')@functools.lru_cache(maxsize=128, typed=False)
defweb_lookup(url, saved={}):
ifurlinsaved:
returnsaved[url]
page=urllib.urlopen(url).read()
saved[url] =pagereturnpage# the python way@lru_cachedefweb_lookup(url):
returnurllib.urlopen(url).read()Anytime your setup and teardown logic get repeated in your code you want a context manager to improve it
old_context=getcontext().copy()
getcontext().prec=50printDecimal(355) /Decimal(113)
setcontext(old_context)
# the python waywithlocalcontext(Context(prec=50)):
printDecimal(355) /Decimal(113)
try:
os.remove('somefile.tmp')
exceptOSError:
pass# the python way@contextlib.contextmanagerdefignored(*exceptions):
try:
yieldexceptexceptions:
passwithignored(OSError):
os.remove('somefile.tmp')One logical line of code equals one sentence in English
data= [1, 2, 3, 4]
ifany(x>3forxindata):
print('Un élément est supérieur à 3')