Python3 速成

Python3 速成


2019-01-28

算法

整除使用双斜线

函数

函数可指定默认值,还可以在传参时指定参数。

1
2
3
4
5
6
7
8
9
10
11
def say(message = 'hello')
print(message)
say('nihao') # 'nihao'
say() # 'hello'



def subtract(a = 0, b = 0)
return a - b
subtract(10, 5) # 5
subtract(b = 5) # -5

字符串

命令 r 可以生成一个原始字符串,不被转译。

三个引号可以创建多行字符串数据。

1
2
3
4
raw_str = r'\t'
multi_line_str = """This is first line
This is second line
This is third line"""

列表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
x = range(10)	# 是列表[0, 1, ..., 9]
zero = x[0] # 等于0,列表是0-索引的
one = x[1] # 等于1
nine = x[-1] # 等于9,最后一个元素的Python惯用法
eight = x[-2] # 等于8,倒数第二个元素的Pyhton惯用法
x[0] = -1 # 现在x是[-1, 1, 2, 3, ..., 9]

# 切片
first_three = x[:3] # [-1, 1, 2]
three_to_end = x[3:] # [3, 4, ..., 9]
one_to_four = x[1:5] # [1, 2, 3, 4]
last_three = x[-3:] # [7, 8, 9]
without_first_and_last = x[1:-1] # [1, 2, ..., 8]
copy_of_x = x[:] # [-1, 1, 2, ..., 9]

列表的串联方法。

1
2
3
4
5
6
7
x = [1, 2, 3]
x.extend([4, 5, 6]) # x is [1, 2, 3, 4, 5, 6]

x = [1, 2, 3]
y = x + [4, 5, 6] # y is [1, 2, 3, 4, 5, 6]

_, y = [1, 2] # y is 2, ingore _

元组

元组和列表都可以进行多重赋值。

1
2
x, y = 1, 2
x, y = y, x

字典

1
2
3
4
5
6
7
8
example_dict = {}
example_dict = {'a': 10, 'b': 80}
has_in = 'a' in example_dict # 直接 in 是确认 key 是否存在

# get 可以避免 key 不存在时报异常
value = example_dict.get('a', 0) # 10
value = example_dict.get('c', 0) # 0
value = example_dict.get('d') # None

重要:items 函数可以打印 [(键,值)] 的列表,经常和lambda一起用。(keys values 函数顾名思义)

defaultdict

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from collections import defaultdict

# defaultdict 是一个带有默认值的 dict

dd_int = defaultdict(int)
dd_int['x'] = 1 # 默认为0

dd_list = defaultdict(list)
dd_list[0].append(1) # dd_list is { 0 : [1] }

dd_dict = defaultdict(dict)
dd_dict['x']['y'] = 'z' # { 'x' : { 'y' : 'z' }}

dd_pair = defaultdict(lambda: [0, 0])
dd_pair[2][1] = 1 # {2: [0, 1]}

Counter

1
2
from collections import Counter
c = Counter([0, 1, 3, 0]) # { 0: 2, 1: 1, 2: 1}

控制流

三元表达式

1
data = 'even' if param % 2 == 0 else 'odd'

真和假

下面值都是假:

1
2
3
4
5
6
7
8
False
None
[ ](一个空 list)
{ }(一个空 dict)
""
set()
0
0.0

可以使用以上值去直接判断:

1
2
3
4
5
6
7
8
9
s = some_function_that_returns_a_string()
if s:
first_char = s[0]
else:
first_char = ""

# 很棒的简写方式
safe_x = s and s[0] # 功能同上,第一个值为真,返回第二个值,否则返回第一个值。
safe_x = s or s[0] # 和and相反,第一个为真返回第一个,否则返回第二个

all 函数 和 any 函数,参数是一个列表,前者都为真返回真,后者一个为真返回真。

排序

sort 对本身排序,sorted 排序返回结果,不改变对象自己。

1
2
3
4
5
6
7
# 可以通过指定函数的结果,进行比较
x = sorted([-4, 1, -2, 3], key=abs, reverse=True) # [-4, 3,-2, 1]

# 从高到低 排序单词和计数
wc = sort(word_count.items(),
key=lambda(word, count): count,
reverse=True)

列表解析

把一个列表通过一定规则转换为另外一个列表、或者改变其中一些元素,或者同时做这两种操作,这种操作叫做列表解析 (list comprehension)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
even_numbers = [x for x in range(5) if x % 2 == 0] # [0, 2, 4]
squares = [x * x for x in range(5)] # [0, 1, 4, 9, 16]
even_squares = [x * x for x in even_numbers] # [0, 4, 16]

# 可以将列表转换为字典或集合
square_dict = {x : x * x for x in range(5)} # {0:0, 1:1, 2:4, 3:9, 4:16}
square_set = {x * x for x in [1, -1]} # {1}

zeroes = [0 for _ in even_numbers] # 忽略原列表的值

# 列表解析可以使用多个for
pairs = [(x, y),
for x in range(10)
for y in range(10)] # (0, 0) (0, 1) ... (0, 9)
# 后面 for 可以使用前面 for 的结果
increasing_pairs = [(x, y)
for x in range(10)
for y in range(x + 1, 10)]

随机性

1
2
3
4
5
6
7
8
9
import random

four_uniform_random = [random.random() for _ in range(4)]

# 设置种子会得到同样的结果
random.seed(5)
randowm.random() # 0.6229016948897019
random.seed(5)
randowm.random() # 0.6229016948897019

random.randrange 可以设置随机数的范围。

1
random.randrange(10) # 从 range(10) 中随机选数

random.shuffle 随机排列列表中的元素。

random.choice 从列表中随机选择一个出来。

random.sample 从列表中随机选择一个样本集出来(不重复选择)。

1
2
3
lottery_numbers = range(60)
winning_numbers = random.sample(lottery_numbers, 6) # 长度为6的列表
four_with_replacement = [random.choice(range(10)) for _ in range(4)] # 可重复选择长度为4的列表

正则表达式

1
2
3
4
5
6
7
import re
print all([ # 结果为 True
not re.match("a", "cat"), # cat 不是 a 开头
re.search("a", "cat"), # cat 中有 a
not re.search("c", "dog"), # dog 中没有 c
3 == len(re.split("[ab]", "carbs")), # 分割掉 ab 之后 长度为3
"R-D-" == re.sub("[0-9]", "-", "R2D2") ] # 替换数字为 -

面向对象编程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 名称遵循驼峰原则
class Set:
"""惯例每一个函数第一个参数都为 self
前后双下划线的函数为类的特殊函数
前边单下划线的成员表示私有(虽然依然可以访问)
"""
def __init__(self, values = None):
self.dict = {}
if values is not None:
for value in values:
self.add(value)

def __repr__(self):
"""类似 Java 中的 toString"""
return "Set:" + str(self.dict.keys())

def add(self, value):
self.dict[value] = True

def remove(self, value):
del self.dict[value]

def contains(self, item):
return item in self.dict

函数式工具

1
2
3
4
5
6
7
8
9
10
11
def exp(base, power):
return base ** power

# partial 是一个函数包装器
from functools import partial
two_to_the = partial(exp, 2)
print(two_to_the(3)) # 8

# 也可以指定后面的数:
square_of = partial(exp, power = 2)
print(square_of(3)) # 9

map, reduct 和 filter 函数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
def double(x):
return 2 * x
xs = [1,2,3,4]
twice_xs = [double(x) for x in xs]
twice_xs = map(double, xs)
list_doubler = partial(map, doble)
twice_xs = list_doubler(xs)

# 如果提供了多个列表,可以对带有多个参数的函数使用 map
def multiply(x, y):
return x * y

products = map(multiply, [1, 2], [4, 5]) # [1 * 4, 2 * 5] = [4, 10]

# filter 中做了列表解析的工作
function is_even(x):
return x % 2 == 0

x_even = [x for x in xs if is_even(x)] # [2, 4]
x_even = filter(is_even, xs)
list_evener = partial(filter, is_even)
x_evens = list_evener(xs)

# reduce 结合列表的前2个元素,然后第3个元素,第4个…… 直到最后。
x_product = reduct(mutiply, xs) # 1 * 2 * 3 * 4 = 24
list_product = partial(reduce, mutiply)
x_product = list_product(xs)

枚举

如果想迭代一个列表,同时使用它的元素和索引,可以使用 enumerate ,它会产生(index, element) 元组。

1
2
3
4
for i, document in enumearte(documents):
do_something(i, document)
# 如果只想用到索引,可以忽略元素。
for i, _ in enumerate(documents): do_something(i)

压缩和参数拆分

如果想把两个或多个列表压缩到一起,可以使用zip把多个列表转换为对应元素的元组组成的单个列表里:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
list1 = ['a', 'b', 'c']
list2 = [1, 2, 3]
zip(list1, list2) # [('a', 1), ('b', 2), ('c', 3)]

# 星号执行参数拆分
pairs = [('a', 1), ('b', 2), ('c', 3)]
letters, numbers = zip(*pairs)

# 另外一种参数拆分,使用pair元素作为独立的参数传给zip,结果和上边一样
zip(('a', 1), ('b', 2), ('c', 3))
# [('a', 'b', 'c'), (1, 2, 3)]

# 可以在函数上面使用参数拆分

def add(a, b): return a + b
add(1, 2) # 3
add([1, 2]) # TypeError!
add(*[1, 2]) # 3

可变参数: args 和 kwargs

args 是一个它的未命名参数的元组,而 kwargs 是一个它的已命名参数的 dict。

1
2
3
4
5
6
7
8
def magic(*args, **kwargs):
print("unnamed args:", args)
print("keyword args:", kwargs)
magic(1, 2, key="word", key2="word2")
# unnamed args: (1, 2)
# keyword args: {'key': 'word', 'key2': 'words'}

# 可以使用 list (或 tuple) 和 dict 提供参数。