快开学了梳理下python的基础知识,个人感觉内容不算多😀
另外最近有人问我python应该如何入门,大概要学多久. emmmm我个人感觉一个星期就足够了。

python基础.基础

这部分严格来讲算不上python的知识,应该是学编程的基础知识

  1. python是解释型语言
  2. python官方用的是CPython解释器
  3. python遵循pep8规范,当然你用自己的也行只要语法格式不错都行

如果上述几个点你都弄明白了,那你应该能回答出下面的这个问题:
python的运行速度为什么比C语言慢?
如果你答不上来,那说明你还不太了解,应该回头把基础知识补一下。

数据类型

基本数据类型都大同小异,但python是动态语言定义前不需要声明数据类型

整型(int)

Python可以处理任意大小的整数,当然包括负整数,在程序中的表示方法和数学上的写法一模一样,例如:1,100,-8080,0,等等。

计算机由于使用二进制,所以,有时候用十六进制表示整数比较方便,十六进制用0x前缀和0-9,a-f表示,例如:0xff000xa5b4c3d2,等等。

字符串(String)

字符串是以单引号’或双引号”括起来的任意文本,比如’abc’,”xyz”等等。请注意,’’或””本身只是一种表示方式,不是字符串的一部分,因此,字符串’abc’只有a,b,c这3个字符。如果’本身也是一个字符,那就可以用””括起来,比如”I’m OK”包含的字符是I,’,m,空格,O,K这6个字符。
如果字符串内部既包含'又包含"怎么办?可以用转义字符\来标识,比如:
'I\'m \"OK\"!' => I'm "OK"!
转义字符\可以转义很多字符,比如\n表示换行,\t表示制表符,字符\本身也要转义,所以\\表示的字符就是\
如果字符串内部有很多换行,用\n写在一行里不好阅读,为了简化,Python允许用'''xxxx'''的格式表示多行内容:

1
2
3
4
5
6
7
# 注意这里第一行(line1)是紧跟这'''后面的,如果另起一行则会有空行
>>> print('''line1
line2
line3''')
line1
line2
line3

浮点型(float、double)

浮点数也就是小数,之所以称为浮点数,是因为按照科学记数法表示时,一个浮点数的小数点位置是可变的,比如,1.23x10912.3x108是完全相等的。浮点数可以用数学写法,如1.23,3.14,-9.01,等等。但是对于很大或很小的浮点数,就必须用科学计数法表示,把10用e替代,1.23x109就是1.23e9,或者12.3e80.000012可以写成1.2e-5,等等。

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

布尔型

一个布尔值只有TrueFalse两种值,要么是True,要么是False,在Python中,可以直接用TrueFalse表示布尔值(请注意大小写)。

空值

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

更多扩展

因为本文是笔记所以更详细的就不一一写了,上面这部分的扩充知识会放在这个区域

  1. 字符串和编码
  2. 布尔运算
  3. None到底是什么
  4. 各个类型的强制转换
  5. 数据在计算机内部的样子

数据结构

列表(list)

有学过C的小伙伴应该都听过数组,python的列表其实就是C的数组

创建列表

用法:

1
2
3
>>> classmates = ['Michael', 'Bob', 'Tracy']
>>> classmates
['Michael', 'Bob', 'Tracy']

变量classmates就是一个list。用len()函数可以获得list元素的个数:

1
2
>>> len(classmates)
3

和C语言相比,list里面的元素的数据类型也可以不同,比如:

1
2
3
4
>>> L = ['Apple', 123, True]
>>> s = ['python', 'java', ['asp', 'php'], 'scheme']
>>> len(s)
4

下面是一个套娃List(二维), 要注意嗷!

1
2
3
4
5
>>> p = ['asp', 'php']
>>> s = ['python', 'java', p, 'scheme']
>>> s[2]
['asp', 'php']
#要拿到'php'可以写p[1]或者s[2][1],因此s可以看成是一个二维数组,类似的还有三维、四维……数组,不过很少用到。

增删查改

现在有了一个列表,那怎么读取列表里面的元素?

列表的查询:
通过下标查询(index) => index意为下标、索引

  • 正向查询 => classmates[1] -> Bob
  • 反向查询 => classmates[-2] -> Bob

同样的要想修改列表里面的元素,也是通过下标进行操作

1
2
3
classmates[1] = 'Sarah'
>>> classmates
['Michael', 'Sarah', 'Tracy']

向列表里面增加元素:

1
2
3
>>> classmates.append('Adam')
>>> classmates
['Michael', 'Bob', 'Tracy', 'Adam']

也可以把元素插入到指定的位置,比如索引号1的位置:

1
2
3
>>> classmates.insert(1, 'Jack')
>>> classmates
['Michael', 'Jack', 'Bob', 'Tracy', 'Adam']

删除列表里面的元素:
要删除list末尾的元素,用pop()方法:

1
2
3
4
>>> classmates.pop()
'Adam'
>>> classmates
['Michael', 'Jack', 'Bob', 'Tracy']

要删除指定位置的元素,用pop(i)方法,其中i是索引位置

1
2
3
4
>>> classmates.pop(1)
'Jack'
>>> classmates
['Michael', 'Bob', 'Tracy']

扩充

  1. del的方法来删除列表元素
  2. pop()函数删除列表元素是,怎么接收这个弹出来的元素
  3. 列表的切片操作
  4. 列表反转、排序

元组(tuple)

除了list另一种有序列表叫元组:tuple。tuple和list非常类似,但是tuple一旦初始化就不能修改,比如同样是列出同学的名字:
>>> classmates = ('Michael', 'Bob', 'Tracy')

现在,classmates这个tuple不能变了,它也没有append(),insert()这样的方法。其他获取元素的方法和list是一样的,你可以正常地使用classmates[0],classmates[-1],但不能赋值成另外的元素。

不可变的tuple有什么意义?因为tuple不可变,所以代码更安全。如果可能,能用tuple代替list就尽量用tuple。

tuple的陷阱:当你定义一个tuple时,在定义的时候,tuple的元素就必须被确定下来,比如:

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

如果要定义一个空的tuple,可以写成()

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

但是,要定义一个只有1个元素的tuple,如果你这么定义:

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

定义的不是tuple,是1这个数!这是因为括号()既可以表示tuple,又可以表示数学公式中的小括号,这就产生了歧义,因此,Python规定,这种情况下,按小括号进行计算,计算结果自然是1。

所以,只有1个元素的tuple定义时必须加一个逗号,,来消除歧义:

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

Python在显示只有1个元素的tuple时,也会加一个逗号,,以免你误解成数学计算意义上的括号。

最后来看一个“可变的”tuple:

1
2
3
4
5
>>> t = ('a', 'b', ['A', 'B'])
>>> t[2][0] = 'X'
>>> t[2][1] = 'Y'
>>> t
('a', 'b', ['X', 'Y'])

字典(dict)

oh!终于写到字典了,字典是一个很好用的东西。如果你学过web开发或者了解过前后端分离那你一定听说过json,JavaScript的对象表示法
言归正传,在python里面这种数据结构叫字典

字典初始化&基础

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

举个例子,假设要根据同学的名字查找对应的成绩,如果用list实现,需要两个list:

1
2
names = ['Michael', 'Bob', 'Tracy']
scores = [95, 75, 85]

给定一个名字,要查找对应的成绩,就先要在names中找到对应的位置,再从scores取出对应的成绩,list越长,耗时越长。

如果用dict实现,只需要一个“名字”-“成绩”的对照表,直接根据名字查找成绩,无论这个表有多大,查找速度都不会变慢。用Python写一个dict如下:

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

字典的创建有很多方法,下面列举几种:

1
2
3
>>> temp_dict['Adam'] = 67
>>> temp_dict['admin']
67

由于一个key只能对应一个value,所以,多次对一个key放入value,后面的值会把前面的值冲掉:

1
2
3
4
5
6
>>> temp_dict['Jack'] = 90
>>> temp_dict['Jack']
90
>>> temp_dict['Jack'] = 88
>>> temp_dict['Jack']
88

注意,如果key不存在,dict就会报错:

1
2
3
4
>>> temp_dict['Thomas']
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 'Thomas'

要避免key不存在的错误,有两种办法,一是通过in判断key是否存在:

1
2
>>> 'Thomas' in d
False

二是通过dict提供的get()方法,如果key不存在,可以返回None,或者自己指定的value:

1
2
3
>>> d.get('Thomas')
>>> d.get('Thomas', -1)
-1

注意:返回None的时候Python的交互环境不显示结果。

字典删除

要删除一个key,用pop(key)方法,对应的value也会从dict中删除:

1
2
3
4
>>> d.pop('Bob')
75
>>> d
{'Michael': 95, 'Tracy': 85}

后话

请务必注意,dict内部存放的顺序和key放入的顺序是没有关系的。

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

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

查找和插入的时间随着元素的增加而增加;
占用空间小,浪费内存很少。
所以,dict是用空间来换取时间的一种方法。

扩充

  1. 字典这种数据结构是怎么实现快速查找的
  2. 哈希函数是什么

流程控制

流程控制在每门语言中都是基础的一部分
而python的流程控制有:

  1. for循环
  2. while循环
  3. if

if条件判断

语法格式:

1
2
3
4
5
6
7
8
if <条件判断1>:
<执行1>
elif <条件判断2>:
<执行2>
elif <条件判断3>:
<执行3>
else:
<执行4>

计算机之所以能做很多自动化的任务,因为它可以自己做条件判断。

比如,输入用户年龄,根据年龄打印不同的内容,在Python程序中,用if语句实现:

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

根据Python的缩进规则,如果if语句判断是True,就把缩进的两行print语句执行了,否则,什么也不做。

也可以给if添加一个else语句,意思是,如果if判断是False,不要执行if的内容,去把else执行了:

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

注意不要少写了冒号:

当然上面的判断是很粗略的,完全可以用elif做更细致的判断:

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

for循环

for循环是python两种中的一种
for循环的语法格式是:for x in xxx:; 依次把list或tuple中的每个元素迭代出来,看例子:

1
2
3
4
5
6
7
names = ['Michael', 'Bob', 'Tracy']
for name in names:
print(name)
# 执行这段代码,会依次打印names的每一个元素:
Michael
Bob
Tracy

所以for x in ...循环就是把每个元素代入变量x,然后执行缩进块的语句。
上面例子里面的names一般叫作迭代对象。

while循环

python除了for循环,第二种循环是while循环,只要条件满足,就不断循环,条件不满足时退出循环。比如我们要计算100以内所有奇数之和,可以用while循环实现:

1
2
3
4
5
6
7
sum = 0
n = 99
while n > 0:
sum = sum + n
n = n - 2
print(sum)
# 在循环内部变量n不断自减,直到变为-1时,不再满足while条件,循环退出。

扩充

  1. range()函数
  2. breakcontinue
  3. python里面迭代对象是什么

函数(function)

什么是函数? 数学里面的函数吗? 抽象的讲确实是数学里面的函数,传入自变量得到因变量。但我们也可以把函数理解成积木块,把一些常用的代码块封装起来。方便使用的块块
或者可以把函数理解成接口,我们传递东西进去,它返回东西出来

调用函数

我们之前用的print函数在屏幕上打印信息,比如打印Hello World!则要调用print('Hello World!'),所以函数的格式:[函数名](<传递参数>)

函数定义(初始化)

在python里面,函数是用def关键字来定义的,比如:def my_function():
函数名其实也是变量名,因此函数名的定义规则和变量一样

函数的参数

Python的函数定义非常简单,但灵活度却非常大。除了正常定义的必选参数外,还可以使用默认参数、可变参数和关键字参数,使得函数定义出来的接口,不但能处理复杂的参数,还可以简化调用者的代码。
一个简单的例子 => 定义一个计算x^2的函数

1
2
3
4
5
6
7
def power(x):
return x * x

>>> power(5)
25
>>> power(15)
225

现在,如果我们要计算x3怎么办?可以再定义一个power3函数,但是如果要计算x4、x5……怎么办?我们不可能定义无限多个函数。

你也许想到了,可以把power(x)修改为power(x, n),用来计算xn,说干就干:

1
2
3
4
5
6
7
8
9
10
def power(x, n):
s = 1
while n > 0:
n = n - 1
s = s * x
return s
>>> power(5, 2)
25
>>> power(5, 3)
125

新的power(x, n)函数定义没有问题,但是,旧的调用代码失败了,原因是我们增加了一个参数,导致旧的代码因为缺少一个参数而无法正常调用。

这个时候,默认参数就排上用场了。由于我们经常计算x2,所以,完全可以把第二个参数n的默认值设定为2:

1
2
3
4
5
6
7
8
9
10
def power(x, n=2):
s = 1
while n > 0:
n = n - 1
s = s * x
return s
>>> power(5)
25
>>> power(5, 2)
25

默认参数需要注意的点 观察下面这个函数,思考一下运行两次add_end()的结果

1
2
3
def add_end(L=[]):
L.append('END')
return L
1
2
3
4
>>> add_end()
['END', 'END']
>>> add_end()
['END', 'END', 'END']

Python函数在定义的时候,默认参数L的值就被计算出来了,即[],因为默认参数L也是一个变量,它指向对象[],每次调用该函数,如果改变了L的内容,则下次调用时,默认参数的内容就变了,不再是函数定义时的[]了。

可变参数
在Python函数中,还可以定义可变参数。顾名思义,可变参数就是传入的参数个数是可变的,可以是1个、2个到任意个,还可以是0个。

我们以数学题为例子,给定一组数字a,b,c……,请计算a2 + b2 + c2 + ……。

要定义出这个函数,我们必须确定输入的参数。由于参数个数不确定,我们首先想到可以把a,b,c……作为一个list或tuple传进来,这样,函数可以定义如下:

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

如果利用可变参数,调用函数的方式可以简化成这样:

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

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

1
2
def person(name, age, **kw):
print('name:', name, 'age:', age, 'other:', kw)

函数person除了必选参数nameage外,还接受关键字参数kw。在调用该函数时,可以只传入必选参数:

1
2
>>> person('Michael', 30)
name: Michael age: 30 other: {}

递归函数

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

举个例子,我们来计算阶乘n! = 1 x 2 x 3 x ... x n,用函数fact(n)表示,可以看出:

fact(n)=n!=1\times2\times3\times\cdot\cdot\cdot\times(n-1)\times n=(n-1)!\times n=fact(n-1)\times nfact(n)=n!=1×2×3×⋅⋅⋅×(n−1)×n=(n−1)!×n=fact(n−1)×n

所以,fact(n)可以表示为n x fact(n-1),只有n=1时需要特殊处理。

于是,fact(n)用递归的方式写出来就是:

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

扩充

  1. 函数参数的传递过程(形参和实参的区别)
  2. 匿名函数
  3. 一元表达式

总结

上述的这些既可以说是python的入门,也可以说是编程的入门。
还有更多的python的我把它们归类在python的高级特性范围,本文参考廖神的python入门后续请自己前往学习。
大概的梳理一下剩下的知识点,仅个人能想到的部分,更多更系统的大纲请看专业的教材

  1. 面向对象
  2. lamba函数
  3. IO
  4. 进程和线程
  5. 正则
  6. 网络编程(socket)
  7. 高级特性->切片等等

参考链接:廖雪峰官网