Python基础(一)

代码星冰乐

专注成就未来

首页 归档 关于

Python基础(一)

Nov 27, 2016 | ChanghuiN | Python | 阅读
文章目录
  1. 1. Python基础
    1. 1.1. 数据类型和变量
      1. 1.1.1. 数据类型
      2. 1.1.2. 变量
      3. 1.1.3. 字符串和编码
    2. 1.2. list和tuple
      1. 1.2.1. list
      2. 1.2.2. tuple
    3. 1.3. 条件判断
    4. 1.4. 循环
      1. 1.4.1. for in循环
      2. 1.4.2. while循环
      3. 1.4.3. break及continue
    5. 1.5. dict和set
      1. 1.5.1. dict
      2. 1.5.2. set
  2. 2. 函数
    1. 2.1. 函数的参数
      1. 2.1.1. 默认参数
      2. 2.1.2. 可变参数
      3. 2.1.3. 关键字参数
      4. 2.1.4. 命名关键字参数
      5. 2.1.5. 参数组合
  3. 3. 高级特性
    1. 3.1. 切片
    2. 3.2. 迭代
    3. 3.3. 列表生成式
    4. 3.4. 生成器
    5. 3.5. 迭代器
  4. 4. 函数式编程
    1. 4.1. 高阶函数
      1. 4.1.1. map/reduce
      2. 4.1.2. filter
      3. 4.1.3. sorted
    2. 4.2. 返回函数
    3. 4.3. 匿名函数
    4. 4.4. 装饰器
    5. 4.5. 偏函数

作 者:ChanghuiN
原文链接:https://www.hchstudio.cn/article/2016/396e/
版权声明:非特殊声明均为本站原创作品,转载时请注明作者和原文链接。


由于版权原因,请阅读原文 --> Python基础(一)

关注我们

作 者:ChanghuiN
原文链接:https://www.hchstudio.cn/article/2016/396e/
版权声明:非特殊声明均为本站原创作品,转载时请注明作者和原文链接。

作 者:ChanghuiN
原文链接:https://www.hchstudio.cn/article/2016/396e/
版权声明:非特殊声明均为本站原创作品,转载时请注明作者和原文链接。

此为学习Python的基础语法笔记,如有错误,欢迎评论纠正。

Python基础

Python的语法比较简单,采用缩进方式。

以#开头的语句是注释,解释器会忽略掉注释。其他每一行都是一个语句,当语句以冒号:结尾时,缩进的语句视为代码块。

Python程序是大小写敏感的,如果写错了大小写,程序会报错。

数据类型和变量

数据类型

  • 整数
  • 浮点数
  • 字符串 (Python还允许用r’’表示’’内部的字符串默认不转义)
  • 布尔值 (True, False)
  • 空值 None

变量

  • 变量 ( a = 1 )
  • 常量 ( 没有固定语法,通常用全部大写的变量名表示常量 )

字符串和编码

Python提供了ord()函数获取字符的整数表示,chr()函数把编码转换为对应的字符。

1
2
3
4
>>> ord('A')
65
>>> chr(66)
'B'

Python对bytes类型的数据用带b前缀的单引号或双引号表示:

1
x = b'ABC'

以Unicode表示的str通过encode()方法可以编码为指定的bytes

1
2
3
4
>>> 'ABC'.encode('ascii')
b'ABC'
>>> '中文'.encode('utf-8')
b'\xe4\xb8\xad\xe6\x96\x87'

在bytes中,无法显示为ASCII字符的字节,用\x##显示。

反过来,如果我们从网络或磁盘上读取了字节流,那么读到的数据就是bytes。要把bytes变为str,就需要用decode()方法。

1
2
3
4
>>> b'ABC'.decode('ascii')
'ABC'
>>> b'\xe4\xb8\xad\xe6\x96\x87'.decode('utf-8')
'中文'

要计算str包含多少个字符,可以用len()函数

1
2
3
4
>>> len('ABC')
3
>>> len('中文')
2

len()函数计算的是str的字符数,如果换成bytes,len()函数就计算字节数

1
2
3
4
>>> len(b'ABC')
3
>>> len('中文'.encode('utf-8'))
6

在Python中,采用的格式化方式和C语言是一致的,用%实现。

1
2
3
4
>>> '%2d-%02d' % (3, 1)
' 3-01'
>>> '%.2f' % 3.1415926
'3.14'

常见的占位符有:

header 1 | header 2
| — | — |
| %d | 整数 |
%f | 浮点数
%s | 字符串
%x | 十六进制整数

list和tuple

list

1
>>> classmates = ['Michael', 'Bob', 'Tracy']
  • 增加元素:classmates.append(‘Adam’)
  • 插入元素到指定位置:classmates.insert(1, ‘Jack’)
  • 删除末尾元素:classmates.pop()
  • 删除指定位置元素:classmates.pop(1)
  • 替换元素:classmates[1] = ‘Sarah’

tuple

tuple和list非常类似,但是tuple一旦初始化就不能修改。

1
>>> classmates = ('Michael', 'Bob', 'Tracy')

条件判断

1
2
3
4
5
6
7
age = 3
if age >= 18:
print('adult')
elif age >= 6:
print('teenager')
else:
print('kid')

循环

for in循环

1
2
3
names = ['Michael', 'Bob', 'Tracy']
for name in names:
print(name)

while循环

1
2
3
4
5
6
sum = 0
n = 99
while n > 0:
sum = sum + n
n = n - 2
print(sum)

break及continue

dict和set

dict

Python内置了字典:dict的支持,dict全称dictionary,在其他语言中也称为map,使用键-值(key-value)存储,具有极快的查找速度。

1
2
3
>>> d = {'Michael': 95, 'Bob': 75, 'Tracy': 85}
>>> d['Michael']
95

和list比较,dict有以下几个特点:

  1. 查找和插入的速度极快,不会随着key的增加而变慢;
  2. 需要占用大量的内存,内存浪费多。

set

set和dict类似,也是一组key的集合,但不存储value。key不能重复。

1
2
3
>>> s = set([1, 2, 3])
>>> s
{1, 2, 3}

  • add(key)
  • remove(key)

函数

在Python中,定义一个函数要使用def语句,依次写出函数名、括号、括号中的参数和冒号:,然后,在缩进块中编写函数体,函数的返回值用return语句返回。  

函数体内部可以用return随时返回函数结果。  
函数执行完毕也没有return语句时,自动return None。  
函数可以同时返回多个值,但其实就是一个tuple。  

1
2
3
4
5
def my_abs(x):
if x >= 0:
return x
else:
return -x

支持默认参数、可变参数和关键字参数。

函数的参数

默认参数

1
2
3
4
5
6
def enroll(name, gender, age=6, city='Beijing'):
print('name:', name)
print('gender:', gender)
print('age:', age)
print('city:', city)
enroll('Adam', 'M', city='Tianjin')

定义默认参数要牢记一点:默认参数必须指向不变对象!

可变参数

1
2
3
4
5
6
def calc(*numbers)
sum = 0
for n in numbers:
sum = sum + n * n
return sum
calc(1,2)

关键字参数

可变参数允许你传入0个或任意个参数,这些可变参数在函数调用时自动组装为一个tuple。而关键字参数允许你传入0个或任意个含参数名的参数,这些关键字参数在函数内部自动组装为一个dict。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
def person(name, age, **kw):
if 'city' in kw:
# 有city参数
pass
if 'job' in kw:
# 有job参数
pass
print('name:', name, 'age:', age, 'other:', kw)

>>> person('Bob', 35, city='Beijing')
name: Bob age: 35 other: {'city': 'Beijing'}
>>> person('Adam', 45, gender='M', job='Engineer')
name: Adam age: 45 other: {'gender': 'M', 'job': 'Engineer'}
>>> extra = {'city': 'Beijing', 'job': 'Engineer'}
>>> person('Jack', 24, **extra)
name: Jack age: 24 other: {'city': 'Beijing', 'job': 'Engineer'}

命名关键字参数

命名关键字参数需要一个特殊分隔符,后面的参数被视为命名关键字参数。

1
2
3
4
5
def person(name, age, *,city, job)
print(name,age,city,job)

>>>person('jack',24,city='Beijing',job='Engineer')
Jack 24 Beijing Engineer

参数组合

在Python中定义函数,可以用必选参数、默认参数、可变参数、关键字参数和命名关键字参数,这5种参数都可以组合使用。但是请注意,参数定义的顺序必须是:必选参数、默认参数、可变参数、命名关键字参数和关键字参数。

1
2
3
4
5
6
7
8
9
10
11
def f1(a, b, c=0, *args, **kw):
print('a =', a, 'b =', b, 'c =', c, 'args =', args, 'kw =', kw)

>>> f1(1, 2)
a = 1 b = 2 c = 0 args = () kw = {}
>>> f1(1, 2, c=3)
a = 1 b = 2 c = 3 args = () kw = {}
>>> f1(1, 2, 3, 'a', 'b')
a = 1 b = 2 c = 3 args = ('a', 'b') kw = {}
>>> f1(1, 2, 3, 'a', 'b', x=99)
a = 1 b = 2 c = 3 args = ('a', 'b') kw = {'x': 99}

高级特性

切片

1
L = ['Michael', 'Sarah', 'Tracy', 'Bob', 'Jack']

取前3个元素:

1
>>>L[:3]

所有数,每5个取一个

1
>>>L[::5]

复制一个List

1
>>>L[:]

list、tuple、字符串都可以使用。

迭代

当我们使用for循环时,只要作用于一个可迭代对象,for循环就可以正常运行,而我们不太关心该对象究竟是list还是其他数据类型。通过collections模块的Iterable类型判断:

1
2
3
4
5
6
7
>>>from collections import iterable
>>>isinstance('abc',Iterable)
True
>>>isinstance([1,2,3].iterable)
Ture
>>>isinstance(123,iterable)
False

默认情况下,dict迭代的是key。如果要迭代value,可以用for value in d.values(),如果要同时迭代key和value,可以用for k, v in d.items()。

1
2
3
4
5
6
>>>for x,y in [(1,1),(2,4),(3,9)]
... print(x,y)
...
1 1
2 4
3 9

列表生成式

列表生成式即List Comprehensions,是Python内置的非常简单却强大的可以用来创建list的生成式。

1
2
3
4
5
6
7
>>>[x * x for x in range(1,11) if x % 2 == 0]
[4, 16, 36, 64, 100]
>>> [m + n for m in 'ABC' for n in 'XYZ']
['AX', 'AY', 'AZ', 'BX', 'BY', 'BZ', 'CX', 'CY', 'CZ']
>>> d = {'x': 'A', 'y': 'B', 'z': 'C' }
>>> [k + '=' + v for k, v in d.items()]
['y=B', 'x=A', 'z=C']

生成器

要创建一个generator,有很多种方法。第一种方法很简单,只要把一个列表生成式的[]改成()。

1
2
3
4
5
6
>>> L = [x * x for x in range(10)]
>>> L
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
>>> g = (x * x for x in range(10))
>>> g
<generator object <genexpr> at 0x1022ef630>

如果要一个一个打印出来,可以通过next()函数获得generator的下一个返回值。

定义generator的另一种方法:如果一个函数定义中包含yield关键字,那么这个函数就不再是一个普通函数,而是一个generator:

1
2
3
4
5
6
7
def fib(max):
n, a, b = 0, 0, 1
while n < max:
yield b
a, b = b, a + b
n = n + 1
return 'done'

这里,最难理解的就是generator和函数的执行流程不一样。函数是顺序执行,遇到return语句或者最后一行函数语句就返回。而变成generator的函数,在每次调用next()的时候执行,遇到yield语句返回,再次执行时从上次返回的yield语句处继续执行。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
>>> g = fib(6)
>>> while True:
... try:
... x = next(g)
... print('g:', x)
... except StopIteration as e:
... print('Generator return value:', e.value)
... break
...
g: 1
g: 1
g: 2
g: 3
g: 5
g: 8
Generator return value: done

迭代器

我们已经知道,可以直接作用于for循环的数据类型有以下几种:

  1. 一类是集合数据类型,如list、tuple、dict、set、str等;
  2. 一类是generator,包括生成器和带yield的generator function。

这些可以直接作用于for循环的对象统称为可迭代对象:Iterable。

而生成器不但可以作用于for循环,还可以被next()函数不断调用并返回下一个值,直到最后抛出StopIteration错误表示无法继续返回下一个值了。

可以被next()函数调用并不断返回下一个值的对象称为迭代器:Iterator。

把list、dict、str等Iterable变成Iterator可以使用iter()函数:

1
2
3
4
5
>>> from collections import Iterator
>>> isinstance(iter([]), Iterator)
True
>>> isinstance(iter('abc'), Iterator)
True

函数式编程

高阶函数

把函数作为参数传入,这样的函数称为高阶函数,函数式编程就是指这种高度抽象的编程范式。

  1. 变量可以指向函数。
  2. 函数名也是变量。
  3. 传入函数

map/reduce

map()函数接收两个参数,一个是函数,一个是Iterable,map将传入的函数依次作用到序列的每个元素,并把结果作为新的Iterator返回。

1
2
>>> list(map(str, [1, 2, 3, 4, 5, 6, 7, 8, 9]))
['1', '2', '3', '4', '5', '6', '7', '8', '9']

reduce把一个函数作用在一个序列[x1, x2, x3, …]上,这个函数必须接收两个参数,reduce把结果继续和序列的下一个元素做累积计算,其效果就是:

1
reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)

一个str2int的函数就是:

1
2
3
4
5
6
7
8
9
10
11
12
13
from functools import reduce
def str2int(s)
def fn(x,y)
return x * 10 + y
def char2num(s)
return {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}[s]
return reduce(fn,map(char2num,s))

//用lambda函数进一步简化成:
def char2num(s):
return {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}[s]
def str2int(s):
return reduce(lambda x, y: x * 10 + y, map(char2num, s))

filter

Python内建的filter()函数用于过滤序列。
和map()类似,filter()也接收一个函数和一个序列。和map()不同的是,filter()把传入的函数依次作用于每个元素,然后根据返回值是True还是False决定保留还是丢弃该元素。

1
2
3
4
5
def not_empty(s):
return s and s.strip()

list(filter(not_empty, ['A', '', 'B', None, 'C', ' ']))
# 结果: ['A', 'B', 'C']

sorted

Python内置的sorted()函数就可以对list进行排序:

1
2
>>> sorted([36, 5, -12, 9, -21])
[-21, -12, 5, 9, 36]

此外,sorted()函数也是一个高阶函数,它还可以接收一个key函数来实现自定义的排序,例如按绝对值大小排序:

1
2
>>> sorted([36, 5, -12, 9, -21], key=abs)
[5, 9, -12, -21, 36]

返回函数

高阶函数除了可以接受函数作为参数外,还可以把函数作为结果值返回。

1
2
3
4
5
6
7
def lazy_sum(*args):
def sum():
ax = 0
for n in args:
ax = ax + n
return ax
return sum

匿名函数

当我们在传入函数时,有些时候,不需要显式地定义函数,直接传入匿名函数更方便。

1
2
>>> list(map(lambda x: x * x, [1, 2, 3, 4, 5, 6, 7, 8, 9]))
[1, 4, 9, 16, 25, 36, 49, 64, 81]

装饰器

现在,假设我们要增强now()函数的功能,比如,在函数调用前后自动打印日志,但又不希望修改now()函数的定义,这种在代码运行期间动态增加功能的方式,称之为“装饰器”(Decorator)。

1
2
3
4
5
6
7
8
9
10
11
12
13
def log(func):
def wrapper(*args, **kw):
print('call %s():' % func.__name__)
return func(*args, **kw)
return wrapper

@log
def now():
print('2015-3-25')

>>> now()
call now():
2015-3-25

把@log放到now()函数的定义处,相当于执行了语句:

1
now = log(now)

如果decorator本身需要传入参数,那就需要编写一个返回decorator的高阶函数,写出来会更复杂。比如,要自定义log的文本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
def log(text):
def decorator(func):
def wrapper(*args, **kw):
print('%s %s():' % (text, func.__name__))
return func(*args, **kw)
return wrapper
return decorator

@log('execute')
def now():
print('2015-3-25')

>>> now()
execute now():
2015-3-25

和两层嵌套的decorator相比,3层嵌套的效果是这样的:

1
>>> now = log('execute')(now)

因为返回的那个wrapper()函数名字就是’wrapper’,所以,需要把原始函数的name等属性复制到wrapper()函数中,否则,有些依赖函数签名的代码执行就会出错。

不需要编写wrapper.name = func.name这样的代码,Python内置的functools.wraps就是干这个事的,所以,一个完整的decorator的写法如下:

1
2
3
4
5
6
7
8
9
10
import functools

def log(text):
def decorator(func):
@functools.wraps(func)
def wrapper(*args, **kw):
print('%s %s():' % (text, func.__name__))
return func(*args, **kw)
return wrapper
return decorator

偏函数

Python的functools模块提供了很多有用的功能,其中一个就是偏函数(Partial function)。要注意,这里的偏函数和数学意义上的偏函数不一样。
functools.partial就是帮助我们创建一个偏函数的,不需要我们自己定义int2(),可以直接使用下面的代码创建一个新的函数int2:

1
2
3
4
>>> import functools
>>> int2 = functools.partial(int, base=2)
>>> int2('1000000')
64

最后,创建偏函数时,实际上可以接收函数对象、*args和**kw这3个参数。
当函数的参数个数太多,需要简化时,使用functools.partial可以创建一个新的函数,这个新函数可以固定住原函数的部分参数,从而在调用时更简单。

关注我们

作 者:ChanghuiN
原文链接:https://www.hchstudio.cn/article/2016/396e/
版权声明:非特殊声明均为本站原创作品,转载时请注明作者和原文链接。

分享
Python
2016学习总结Java NIO笔记
微信关注我们
分类
  • Android8
  • Go4
  • Java59
  • Kafka,Java1
  • Kotlin2
  • Linux1
  • MapReduce1
  • Python2
  • Raft1
  • Redis1
  • ThreadPoolExecutor1
  • go1
  • 工具1
  • 总结8
  • 旅游日记1
标签
Nginx ChanghuiN haifeiWu Android Java 设计模式 hexo Kotlin 算法 MySQL 源码解析 Python Redis golang web Kafka 配置中心 总结 性能优化 旅游日记 Shell Go 问题排查 译文 Docker Spring Boot 工具 学习笔记 WebFlux 性能测试 go 散列表 源码 netty Raft
最近文章
  • Kafka的日志复制机制
  • 从20到21
  • go 并发编程
  • 【译】了解Linux CPU负载-您何时应该担心?
  • Zookeeper 与分布式锁
  • 基于Redis的分布式锁到底安全吗?
  • 【译】Raft 学生指南
  • ThreadPoolExecutor 的简单梳理
  • MapReduce 的简单实现
  • 使用 Map 实现策略模式
福利专区
    免费SSL证书
      阿里云红包
        腾讯云专属福利
        Copyright © 2021 代码星冰乐. Powered by ChanghuiN. 版权所有 晋ICP备15001365号
        特别感谢: 云服务器服务商 、 CDN 服务商