作者:SeanCheney
链接:https://www.jianshu.com/p/b444cda10aa0
从中一部分觉得比较有用的记录下来,
也有一些自己的理解
默认值赋值方法:
if key in some_dict:
value = some_dict[key]
else:
value = default_value
# dict.get方法相当于上面那个默认值方法
value = some_dict.get(key, default_value)
setdefault方法, 没详细看:
In [123]: words = ['apple', 'bat', 'bar', 'atom', 'book']
In [124]: by_letter = {}
In [125]: for word in words:
.....: letter = word[0]
.....: if letter not in by_letter:
.....: by_letter[letter] = [word]
.....: else:
.....: by_letter[letter].append(word)
.....:
In [126]: by_letter
Out[126]:
{'a': ['apple', 'atom'], 'b': ['bat', 'bar', 'book']}
# 相当于下面setdefault
for word in words:
letter = word[0]
by_letter.setdefault(letter, []).append(word)
collections模块有一个很有用的类,defaultdict,进一步简化上面。
传递类型或函数以生成每个位置的默认值:
from collections import defaultdict
by_letter = defaultdict(list)
for word in words:
by_letter[word[0]].append(word)
列表、集合和字典推导式(好用):
# 它允许用户方便的从一个集合过滤元素,形成列表,
# 在传递参数的过程中还可以修改元素。
strings = ['a', 'as', 'bat', 'car', 'dove', 'python']
[x.upper() for x in strings if len(x) > 2]
Out[155]: ['BAT', 'CAR', 'DOVE', 'PYTHON']
用相似的方法,还可以推导集合和字典。字典的推导式如下所示:
dict_comp =
{key-expr : value-expr for value in collection if condition}
集合的推导式与列表很像,只不过用的是尖括号:
set_comp = {expr for value in collection if condition}
与列表推导式类似,集合与字典的推导也很方便,而且使代码的读写都很容易。来看前面的字符串列表。假如我们只想要字符串的长度,用集合推导式的方法非常方便:
In [156]: unique_lengths = {len(x) for x in strings}
In [157]: unique_lengths
Out[157]: {1, 2, 3, 4, 6}
map函数可以进一步简化:
In [158]: set(map(len, strings))
Out[158]: {1, 2, 3, 4, 6}
多层for循环
In [164]: some_tuples = [(1, 2, 3), (4, 5, 6), (7, 8, 9)]
In [165]:
flattened = [x for tup in some_tuples for x in tup]
In [166]: flattened
Out[166]: [1, 2, 3, 4, 5, 6, 7, 8, 9]
记住,for表达式的顺序是与嵌套for循环的顺序一样(而不是列表推导式的顺序):
flattened = []
for tup in some_tuples:
for x in tup:
flattened.append(x)
你可以有任意多级别的嵌套,但是如果你有两三个以上的嵌套,你就应该考虑下代码可读性的问题了。分辨列表推导式的列表推导式中的语法也是很重要的:
In [167]: [[x for x in tup] for tup in some_tuples]
Out[167]: [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
这段代码产生了一个列表的列表,而不是扁平化的只包含元素的列表。
函数相关
位置参数与关键参数
def params_practice(x, y, z=1.5):
print(x, y, z)
params_practice(y=1,x=2,z=3)
Out[167]: 2 1 3
params_practice(y=1,x=2)
Out[168]: 2 1 1.5
函数可以返回多个值,大概如下
def f():
a = 5
b = 6
c = 7
return {'a' : a, 'b' : b, 'c' : c}
处理字符格式
import re
states = [' Alabama ', 'Georgia!', 'Georgia',
'georgia', 'FlOrIda', 'south carolina##', 'West virginia?']
def clean_strings(str):
return [re.sub('[#!?]', '', x.strip()).title()
for x in str]
Out[169]: ['Alabama',
'Georgia',
'Georgia',
'Georgia',
'Florida',
'South Carolina',
'West Virginia']
生成器
能以一种一致的方式对序列进行迭代(比如列表中的对象或文件中的行)是Python的一个重要特点。这是通过一种叫做迭代器协议(iterator protocol,它是一种使对象可迭代的通用方式)的方式实现的,一个原生的使对象可迭代的方法。比如说,对字典进行迭代可以得到其所有的键:
In [180]: some_dict = {'a': 1, 'b': 2, 'c': 3}
In [181]: for key in some_dict:
.....: print(key)
a
b
c
当你编写for key in some_dict时,Python解释器首先会尝试从some_dict创建一个迭代器:
In [182]: dict_iterator = iter(some_dict)
In [183]: dict_iterator
Out[183]: <dict_keyiterator at 0x7fbbd5a9f908>
迭代器是一种特殊对象,它可以在诸如for循环之类的上下文中向Python解释器输送对象。大部分能接受列表之类的对象的方法也都可以接受任何可迭代对象。比如min、max、sum等内置方法以及list、tuple等类型构造器:
In [184]: list(dict_iterator)
Out[184]: ['a', 'b', 'c']
生成器(generator)是构造新的可迭代对象的一种简单方式。一般的函数执行之后只会返回单个值,而生成器则是以延迟的方式返回一个值序列,即每返回一个值之后暂停,直到下一个值被请求时再继续。要创建一个生成器,只需将函数中的return替换为yeild即可:
def squares(n=10):
print('Generating squares from 1 to {0}'.format(n ** 2))
for i in range(1, n + 1):
yield i ** 2
调用该生成器时,没有任何代码会被立即执行:
In [186]: gen = squares()
In [187]: gen
Out[187]: <generator object squares at 0x7fbbd5ab4570>
直到你从该生成器中请求元素时,它才会开始执行其代码:
In [188]: for x in gen:
.....: print(x, end=' ')
Generating squares from 1 to 100
1 4 9 16 25 36 49 64 81 100
生成器表达式
另一种更简洁的构造生成器的方法是使用生成器表达式(generator expression)。这是一种类似于列表、字典、集合推导式的生成器。其创建方式为,把列表推导式两端的方括号改成圆括号:
In [189]: gen = (x ** 2 for x in range(100))
In [190]: gen
Out[190]: <generator object <genexpr> at 0x7fbbd5ab29e8>
它跟下面这个冗长得多的生成器是完全等价的:
def _make_gen():
for x in range(100):
yield x ** 2
gen = _make_gen()
生成器表达式也可以取代列表推导式,作为函数参数:
In [191]: sum(x ** 2 for x in range(100))
Out[191]: 328350
In [192]: dict((i, i **2) for i in range(5))
Out[192]: {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}