Python 基础知识

人生苦短,我学Python

Python 语言已经在大数据、机器学习等领域胜出,这是毋庸置疑的事实了。它以简洁、优雅的语言风格征服了程序员和非专业程序员。并且,它还是一种非常容易学的语言。所以,学习 Python性价比最高。

以上是一堆废话。。。

变量和数据类型

数据类型

整数

Python 可以处理任意大小的整数,自然包括负整数,在Python程序中,整数的表示方法和数学上的写法一模一样,例如1100-1000,等等。
计算机由于使用二进制,所以,有时候用十六进制表示整数比较方便,十六进制用0x前缀和0-9,a-f表示,例如:0xff000xa5b4c3d2,等等。


浮点数

浮点数也就是小数,之所以称为浮点数,是因为按照科学记数法表示时,一个浮点数的小数点位置是可变的,比如 $1.2310^9$ 和$12.310^8$是相等的,浮点数可以用数学写法,如1.233.14-9.01等等。但是对于很大或很小的浮点数,就必须用科学计数法表示,把10用e代替,

整数和浮点数在计算机内部存储方式是不同的,整数运算永远是准确的(除法???),而浮点数运算则可能会四舍五入误差。


字符串

字符串是以''或者""括起来的任意文本,比如‘abc’、“xyz”等。请注意,‘’和“”本身自实一种表达方式,不是字符串的一部分,因此,字符串'abc'只是a, b, c这三个字符。


布尔值

布尔值和布尔代数的表示完全一致,一个布尔值只有TrueFalse两种值,,在Python中,可以直接用True,False代表布尔值(大小写!),也可通过布尔运算计算出来。

布尔值可以用andornot运算。

布尔类型中的短路计算:

  1. 在计算a and b时,如果a是False,则根据与运算法则,整个结果必定为False,因此返回a;如果a是True,则整个计算结果必定取决于b,因此返回b。
  2. 在计算a or b时,如果a是True,则根据或计算规则,整个计算结果必定为True,因此返回a;如果a是False,则整个计算结果必定取决于b,因此返回b。

空值

空值是Python里一个特殊的值,用None表示。None不能理解为0,因为0是有意义的,而None是一个特殊的空值。

此外,Python还提供了列表、字典等多种数据类型,还允许创建自定义数据类型。

Raw字符串和多行字符串

如果一个字符串包含很多需要转义的字符,对每一个字符都进行转义会很麻烦。为了避免这种情况,我们可以在字符串前面加个前缀r,表示这是一个raw字符串,里面的字符就不需要转义了。

例如:

1
print r'\(~_~)/ \(~_~)'

但是r'...'表示法不能表示多行字符串,也不能表示包含''""的字符串

如果要表示多行字符串,可以用'''...'''表示:

1
2
3
'''Line 1
Line 2
Line3'''

同下:

1
'Line 1\nLine 2\nLine 3'

还可以在多行字符串前面加r,把这个多行字符串也变成一个raw字符串

1
2
3
r'''Python is created by "Guido".
It is free and easy to learn.
Let's start learn Python'''

Unicode字符串

因为Python的诞生比Unicode标准发布的时间还要早,所以最早的Python只支持ASCII编码,普通的字符串ABC在Python内部都是ASCII编码的。
Python后来添加了对Unicode的支持,以Unicode表示的字符串用u'...'表示,比如

1
print u'中文'

转义:

1
2
u'''第一行
第二行'''

raw + 多行:

1
2
3
ur'''Python的Unicode字符串支持"中文",
"日文",
"韩文"等多种语言

1
2
3
如果中文字符串在Python环境下遇到**UnicodeDecodeError**,这是因为.py文件保存的格式有问题。可以在第一行添加注释
```python
# -*- coding: utf-8 -*-

目的是告诉Python解释器,用UTF-8编码读取源代码

ListTuple元组类型

Python内置的一种数据类型是列表:List。List是一种有序的集合,可以随时添加和删除其中的元素。
List是数学意义上的有序集合,也就是说,List中的元素是按照顺序排列的。

  • append
    添加新元素到尾部,ClassA.append('newBoy')
  • insert
    添加元素到任意位置,ClassA.insert(0, 'anotherBoy')
  • pop
    删除最后一个元素,可传索引定位删除
  • 替换
    对List中的某个索引赋值,就可以直接替换掉原来的元素

Tuple是另一种有序列表,中文翻译为‘元组’。Tuple和List非常相似,但是Tuple一旦创建完毕,就不能修改了。

1
>>> t = ('LiHua', 'HanMeimei', 'Lisa', 'Goudan')

Tuple所谓的不变是说,Tuple的每一个元素,指向永远不变。即指向a(堆),就不能指向b;指向List(栈),就不能指向其他对象,但指向的这个List本身是可变的

Tuple没有append()方法,也没有insert()pop()方法。所以,新同学没法直接往Tuple里面添加,老同学想退出Tuple也不行。
获取Tuple的方法同List[0]

  • 创建空Tuple

    1
    2
    3
    >>> t = ()
    >>> print t
    ()
  • 创建单元素Tuple

    1
    2
    3
    >>> t = (1)
    >>> print t
    1

    这里t不是Tuple,而是整数1???

    因为()即可以表示Tuple,又可以表示括号运算时的优先级,结果(1)被Python解释器计算出结果1,导致我们得到的不是Tuple,而是整数1。

正是因为用()定义单元素的Tuple有歧义,所以Python规定,单元素Tuple要多加一个逗号”,”,这样就避免了歧义:

1
2
3
>>> t = (1,)
>>> print t
(1,)

条件判断和循环

条件判断

基本if语句实现:

1
2
3
4
5
age = 20
if age >= 18:
print 'your age is', age
print 'adult'
print 'END'

注意:if语句后接表达式,然后用:表示代码块开始。

如果在Python交互环境下敲代码,还要特别留意缩进,并且退出缩进还要多敲一行回车

1
2
3
4
5
6
7
>>> age = 20
<<< if age >= 18:
··· print 'your age is', age
··· print 'adult'
···
your age is 20
adult


if … else … 语句实现:

1
2
3
4
if age >= 18:
print 'adult'
else:
print 'teenager'


if … 多个elif … else …语句实现:

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

循环

for循环语句:

1
2
3
L = ['LiHua', 'HanMeimei', 'Lisa', 'Goudan']
for name in L:
print name

while循环语句:

1
2
3
4
5
N = 10
x = 0
while x < N:
print x
x++

每次先判断 x < N,如果为True,则执行循环体的代码块,否则退出循环

break跳出循环:
在for循环或while循环时,使用break语句可直接跳出循环

1
2
3
4
5
6
7
8
sum = 0
x = 1
while True
sum += x
x++
if x > 100:
break
print sum

continue继续循环:
跳过后续循环代码,继续下一次循环。
统计几个分数的平均分

1
2
3
4
5
6
7
8
L = [75, 98, 59, 81, 66, 43, 69, 85]
sum = 0.0
n = 0
for x in L:
if x < 60:
continue
sum += x
n++

0-100只计算奇数的和:

1
2
3
4
5
6
7
8
9
10
sum = 0
n = 0
while True:
x += 1
if x > 100:
break
if x % 2 == 1:
sum += x
continue
print sum

DictSet类型

Dict

Dict类似与Javascript中的Object对象:

1
2
3
4
5
d = {
'LiHua': 95,
'Lisa': 85,
'Goudan': 59
}

len()函数可计算任意集合的长度

1
2
>>> len(d)
3

访问Dict

1
2
3
4
5
6
7
>>> print d['Lihua']
95
>>> print d['ZhaoSi']
Traceback (most recent call last):
file "index.py", line 11, in <module>
print d['ZhaoSi']
KeyError: 'ZhaoSi'

key不存在会报错,避免KeyError发生,有如下方法:

1
2
3
4
5
6
7
8
9
# 判断 key 是否存在,用 in 操作符
if 'ZhaoSi' in d:
print d['ZhaoSi']

# 用 Dict 自身提供的 get 方法
>>> print d.get('LiHua')
95
>>> print d.get('ZhaoSi')
None

set

set 持有一系列元素,这一点和list很像,但是 set 的元素没有重复,而且无序,这点和dict的key很像。

创建set

1
>>> s = set(['A', 'B', 'C'])

可以查看set内容

1
2
>>> print s
set(['A', 'B', 'C'])

in操作符判断元素

1
2
>>> 'Bart' in s
True

将set中的字母小写

1
2
>>> print set([alp.lower() for alp in ['A', 'B', 'C']])
set(['a', 'b', 'c'])

更新set
由于set存储的是一组不重复的无序元素,因此,更新set只做两件事:

  1. 新增
    1
    2
    3
    4
    >>> s = set([1, 2, 3])
    >>> s.add(4)
    >>> print s
    set([1, 2, 3, 4])

如果添加的元素已经存在于set中,add()不会报错,也不会添加进去

  1. 删除
    1
    2
    3
    4
    >>> s = set([1, 2, 3, 4])
    >>> s.remove(4)
    >>> print s
    set([1, 2, 3])

如果删除的元素不存在set中,remove()会报错。需要加判断

函数

常用内置函数

一、数学相关:

  • 绝对值: abs(-1)
  • 最大最小值:max([1, 2, 3])、min([1, 2, 3])
  • 序列长度:len(‘ABC’)、len([1, 2, 3])、len((1, 2, 3))
  • 取模:divmod(5, 2) –> (2, 1)
  • 乘方:pow(2, 3, 4) === 2 ** (3/4)
  • 浮点数:round(1) –> 1.0

二、功能相关

  • 函数是否可调用:callable(func_name)
  • 类型判断:isinstance(2, int)
  • 比较:cmp(x, y) (python3.x已取消)
    x < y (-1) | x == y (0) | x > y (1)
  • 快速生成序列:range(start, stop[, step])
    1
    2
    >>> range(0, 10, 3)
    [0, 3, 6, 9]

三、类型相关

  • int(x) 整型
  • long(x) 长整形
  • float(x) 浮点型
  • complex(x) 复数
  • str(x)
  • list(x)
  • tuple(x) 元组
  • hex(x) 10进制转换为16进制
  • oct(x) 整数转为8进制
  • chr(x) 返回编码x对应的字符
  • ord(x) 返回字符对应的ASC码

四、字符串处理

  1. 首字母大写

    1
    2
    >>> 'hello'.capitalize()
    'Hello'
  2. 字符串替换

    1
    2
    >>> 'hello'.replace('l', 'x')
    'hexxo'

第 3 个参数为替换次数

  1. 字符串切割
    1
    2
    >>> 'hello'.split('l')
    ['he', 'o']

第2个参数是切割次数

五、序列处理函数

  1. len 序列长度
  2. max 序列中最大值
  3. min 序列中最小值
  4. filter 过滤序列

    1
    2
    3
    4
    5
    >>> def is_odd(n):
    ··· return n % 2 == 1
    ···
    >>> print filter(is_odd, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
    [1, 3, 5, 7, 9]
  5. zip 并行遍历

    1
    2
    3
    4
    5
    >>> name = ['Lily', 'Lisa', 'Roe']
    >>> age = [18, 16, 17]
    >>> tel = ['134', '156', '178']
    >>> zip(name, age, tel)
    [('Lily', 18, '134'), ('Lisa', 16, '156'), ('Roe', 17, '178')]
  6. map 并行遍历,可接收function类型参数

    1
    2
    3
    4
    >>> a = [1, 3, 5]
    >>> b = [2, 4, 6]
    >>> map(None, a, b)
    [(1, 2), (3, 4), (5, 6)]
  7. reduce 归并

    1
    2
    3
    4
    5
    6
    7
    >>> def add(x, y) :            # 两数相加
    ... return x + y
    ...
    >>> reduce(add, [1,2,3,4,5]) # 计算列表和:1+2+3+4+5
    15
    >>> reduce(lambda x, y: x+y, [1,2,3,4,5]) # 使用 lambda 匿名函数
    15

sum函数接受一个list作为参数,并返回list所有元素的和,请计算 1*1 + 2*2 + 3*3 + ... + 100*100

1
2
3
4
5
6
7
8
9
L = []
i = 1
while True:
if i > 100:
break
else:
L.append(pow(i, 2))
i += 1
print sum(L)

自定义函数

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

定义一个square_of_sum函数,它接受一个list,返回list中每个元素平方的和。

1
2
3
4
5
6
7
def square_of_sum(L):
count = 0
for item in L:
count += pow(item, 2)
return count

print square_of_sum([1, 2, 3, 4, 5])

函数可返回多值:

1
2
3
4
5
6
7
8
9
import math
def move(x, y, step, angle):
nx = x + step * math.cos(angle)
ny = y + step * math.sin(angle)
return nx, ny
x, y = move(100, 100, 60, math.pi / 6)

print x, y
# 151.961524227 70.0

多值返回其实是tuple

例子🌰:
一元二次方程的定义是:$ax^2 + bx + c = 0$

1
2
3
4
5
6
7
8
import math

def quadratic_equation(a, b, c):
x1 = (-b + math.sqrt(pow(b, 2) - 4 * a * c)) / (2 * a)
x2 = (-b - math.sqrt(pow(b, 2) - 4 * a * c)) / (2 * a)
return x1, x2

print quadratic_equation(2, 3, 0)

递归函数

在函数内部,可以调用其他函数。如果一个函数在内部调用自身本身,这个函数就是递归函数。
举个栗子🌰:

1
fact(n) = n! = 1 * 2 * 3 * ... * n = (n - 1)! * n = fact(n - 1) * n

将fact(n)用递归的方式写出来即为:

1
2
3
4
def fact(n):
if n == 1:
return 1
return n * fact(n - 1)

汉诺塔问题:

汉诺塔(又称河内塔)问题是源于印度一个古老传说的益智玩具。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。

对柱子编号为a, b, c分别代表起始柱、帮忙柱、结束柱,编写函数打印出移动步骤

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
def hanoi(n, a, b, c):
if n == 1:
print a, '-->', c
else:
hanoi(n - 1, a, c, b)
print a, '-->', c
hanoi(n - 1, b, a, c)

hanoi(4, 'A', 'B', 'C')
'''
A --> B
A --> C
B --> C
A --> B
C --> A
C --> B
A --> B
A --> C
B --> C
B --> A
C --> A
B --> C
A --> B
A --> C
B --> C
'''

默认参数

1
2
3
4
5
6
7
8
def greet(str = 'world'):
print 'hello,' , str + '.'

# hello, world.
greet()

# hello, Goudan.
greet('Goudan')

可变形参

1
2
def fn(*args):
print args

可变参数的名字前面有个*

1
2
3
4
5
6
>>> fn()
()
>>> fn('a')
('a',)
>>> fn('a', 'b')
('a', 'b')

Python解释器会把传入的一组参数组装为一个tuple传递为可变参数,因此,在函数内部,直接把变量args看成一个tuple就好了🙆‍

举个栗子🌰:
计算平均值

1
2
3
4
5
6
7
8
9
def average(*args):
l = len(args)
count = 0.0
if l == 0:
return count
else:
for item in args:
count += item
return count / l

切片

截取一个list的部分元素,python提供切片(Slice)操作符

1
2
3
>>> L = ['LiHua', 'Lisa', 'HanMeimei', 'Goudan', 'ZhaoSi']
>>> L(0:3)
['LiHua', 'Lisa', 'HanMeimei']

L(0:3)表示,从索引0开始取,直到索引3为止。

如果第一个索引是0,可省略不写
只用:,表示从头到尾

切片操作还可以指定第三个参数:

1
2
>>> L[::2]
['LiHua', 'HanMeimei', 'ZhaoSi']

第三个参数表示每N个取一个

举个栗子🌰:
取出1-100的

  1. 前10个数
  2. 3的倍数
  3. 不大于50的5的倍数
  4. 最后10个数
  5. 最后10个5的倍数
    1
    2
    3
    4
    5
    6
    7
    8
    L = range(1, 101)

    print L
    print L[2::3]
    print L[4:50:5]

    print L[-10:]
    print L[4::5][-10:]

对字符串切片

1
2
3
4
5
6
>>> 'ABCDEFG'[:3]
'ABC'
>>> 'ABCDEFG'[-3:]
'EFG'
>>> 'ABCDEFG'[::2]
'ACEG'

迭代

迭代操作就是对于一个集合,无论该集合是有序还是无序,我们用for循环总可以依次取出集合的每一个元素

注意:集合是指包含一组元素的数据结构,包括:

  1. 有序集合:list,tuple,str和unicode
  2. 无序集合:set
  3. 无序集合并且具有key-value对:dict

栗子🌰:
打印出1-100中7的倍数

1
2
3
for i in range(1, 101):
if not i % 7:
print i

索引迭代

Python中,迭代永远是取出元素本身,而非元素索引。
对于有序集合使用enumerate函数拿到索引

1
2
3
4
5
6
7
>>> L = ['LiHua', 'Lisa', 'HanMeimei']
>>> for index, name in enumerate(L):
··· print index, '-', name
···
0 - LiHua
1 - Lisa
2 - HanMeimei

实际上,enumerate函数把['LiHua', 'Lisa', 'HanMeimei']变成了类似:[(0, 'LiHua'), (1, 'Lisa'), (2, 'HanMeimei')]

因此,迭代的每一个元素实际上是Tuple:

1
2
3
4
for t in enumerate(L):
index = t[0]
name = t[1]
print index, '-', name

举个西红柿🍅:
迭代打印出名次 - 名字,名次从 1 开始

1
2
3
4
5
6
7
8
9
L = ['LiHua', 'Lisa', 'HanMeimei', 'Gudan']

for index, name in zip(range(1, len(L) + 1), L):
print index, '-', name

1 - LiHua
2 - Lisa
3 - HanMeimei
4 - Goudan

迭代Dict的value

dict对象中有一个values()方法,这个方法把dict转换成一个包含所有value的list,这样,我们迭代的就是dict的每一个value

1
2
3
4
5
6
7
8
9
10
11
d = {'LiHua': 95, 'Lisa': 85, 'HanMeimei': 89}
print d.values()
# [95, 85, 89]

for v in d.values():
print v
'''
95
85
89
'''

dict除了values()方法外,还有一个intervalues()方法(Python3.x删除)

1
2
3
4
5
6
7
8
9
10
11
d = {'LiHua': 95, 'Lisa': 85, 'HanMeimei': 89}
print d.intervalues()
# <dictionary-valueiterator object at 0x106adbb50>

for v in d.intervalues():
print v
'''
95
85
89
'''

两者不同之处:

  1. values()方法实际上把一个dict转换成了包含value的list
  2. 但是intenvalues()方法不会转换,它会在迭代规程中取出value,所以intervalues()要比values()节省了生成了list的内存
  3. 打印intenvalues()返回值是<dictionary-valueiterator>对象,

迭代key、value

1
2
3
>>> d = {'LiHua': 95, 'Lisa': 85, 'HanMeimei': 89}
>>> print d.items()
[('LiHua', 95), ('Lisa', 85), ('HanMeimei', 89)]

items()方法把dict对象转换成了包含tuple的list,对list进行迭代可同时获得key和value

1
2
3
4
5
6
7
8
9
>>> for key, value in d.items():
··· print key, '-', value
···

'''
LiHua - 95
Lisa - 85
HanMeimei - 89
'''

values()有一个itervalues()类似,items()也有一个对应的iteritems()(Python3废止),iteritems()不把dict转换为list,而是在迭代过程中不断给出tuple,所以iteritems()不占用额外内存。

列表生成式

生成列表

要生成list[1, 2, 3, 4, 5, 6, 7, 8, 9, 10],可以用range(1, 11)

1
2
>>> range(1, 11)
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

但生成[1*1, 2*2, 3*3, 4*4, 5*5, 6*6, 7*7, 8*8, 9*9, 10*10]要怎么做呢?
方法一:循环

1
2
3
4
5
6
>>> L = []
>>> for x in range(1, 11):
··· L.append(x*x)
···
>>> L
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

但是循环太繁琐,而列表生成式则可以用一行语句代替:

1
2
>>> [x * x for x in range(1, 11)]
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

这种写法就是Python特有的列表生成式
举个西瓜🍉:
利用列表生成式生成列表[1 2, 3 4, 5 6, …, 99 100]

1
>>> print [x * (x - 1) for x in range(1, 100, 2)]

复杂表达式

假设有如下dict:

1
d = {'LiHua': 95, 'Lisa': 85, 'HanMeimei': 89}

完全可以通过复杂的列表生成式变为html表格:

1
2
3
4
5
tds = ['<tr><tds>%s</td><td>%s</td></tr>' % (name, score) for name, score in d.items()]
print '<table>'
print '<tr><td>Name</td><td>Value</td></tr>'
print '\n'.join(tds)
print '</table>'

字符串可以通过%进行格式化,用指定的参数替代%s。字符串的join()方法可以把一个list拼接成一个字符串。

条件过滤

列表生成式的for循环后面还可以加上if判断
只要偶数的平方

1
2
>>> [x * x for x in range(1, 11) if x % 2 == 0]
[4, 16, 36, 64, 100]

举个锤子🔨:
将list中所有字符串变为大写后返回,忽略非字符串

1
2
3
4
5
def toUppers(L):
return [x.upper() for x in L if isinstance(x, str)]
print toUppers(['Hello', 'world', 101])

# ['HELLO', 'WORLD']

多层表达式

for循环可以嵌套,因此在列表生成式中,也可以用多层for循环生成;列表

1
2
>> [m + n for m in 'ABC' for n in '123']
['A1', 'A2', 'A3', 'B1', 'B2', 'B3', 'C1', 'C2', 'C3']

举个热狗🌭:
利用三层循环找出对称的3位数。例如,121就是对称数,因为从右到左倒过来还是121。

方法一、双层循环

1
>>> print [m * 100 + n * 10 + m for m in range(1, 10) for n in range(0, 10)

方法二、取模求商

1
>>> print [m for m in range(100, 1000) if m / 100 == a % 10]

最后更新: 2018年11月24日 11:34

原始链接: https://fw6.github.io/2018/11/20/Python-基础知识学习/

× 请我吃糖~
打赏二维码