自学python3教程_Python3 简明教程学习(上)

一、开始 Python 之旅交互模式

1249675-20180315203300065-1761036868.png

1.Ctrl + D 输入一个 EOF 字符来退出解释器,也可以键入 exit() 来退出

2.#!/usr/bin/env python3 中#!称为 Shebang,目的是告诉shell使用Python 解释器执行其下面的代码。

1249675-20180315203311170-1459672120.png

3.注意遵守以下约定:

使用 4 个空格来缩进

永远不要混用空格和制表符

在函数之间空一行

在类之间空两行

字典,列表,元组以及参数列表中,在 , 后添加一个空格。对于字典,: 后面也添加一个空格

在赋值运算符和比较运算符周围要有空格(参数列表中除外),但是括号里侧不加空格:a = f(1, 2) + g(3, 4)

4.模块是包含能复用的代码的文件,包含了不同的函数定义,变量。模块文件通常以 .py 为扩展名,在使用模块前先导入它。

1249675-20180315203305039-895781066.png

二、变量和数据类型

1.关键字(不能用于通常的标识符)

1249675-20180315203306953-1314569159.png

2.定义变量

不需要为变量指定数据类型,操作字符串时用单引号或双引号括起来

3.从键盘读取输入

number = int(input("Enter an integer: "))

4.在一行内将多个值赋值给多个变量

>>> a , b = 4, 5

>>> a

4

>>> b

5

用逗号创建元组,在赋值语句的右边创建元组称这为元组封装(tuple packing),赋值语句的左边做的是元组拆封 (tuple unpacking)。

三、运算符和表达式

divmod()

divmod()函数把除数和余数运算结果结合起来,返回一个包含商和余数的元组(a // b, a % b):

1249675-20180315091841981-1812916024.png

若现在通过获得用户输入的天数,算出月份数和天数,则可以使用该函数轻松get到答案:

#!/usr/bin/env python3

days = int(input("Enter days: "))

print("Months = {} Days = {}".format(*divmod(days, 30))) 用 * 运算符拆封这个元组

1249675-20180315092417110-884580155.png

整除

如果要进行整除,使用 // 运算符,它将返回商的整数部分:

1249675-20180315091204360-819172239.png

思考:如果是12 / 3,结果是多少呢?大家一定会说是不是傻?肯定是4啊!那试试呗:

1249675-20180315205925398-1429511430.png

和你想的不一样吧!所以/不管是不是整除,结果都是浮点数。

逻辑运算符

逻辑运算符 and 和 or 也称作短路运算符:它们的参数从左向右解析,一旦结果可以确定就停止 。作用于一个普通的非逻辑值时,短路运算符的返回值通常是能够最先确定结果的那个操作数。

运算符

逻辑表达式

描述

and

x and y

如果 x 为 False,x and y 返回 False,否则它返回 y 的计算值。

or

x or y

如果 x 是非 0,它返回 x 的值,否则它返回 y 的计算值。

not

not x

如果 x 为 True,返回 False 。如果 x 为 False,它返回 True。

>>> 5 and 4 (5为True还要往后看,所以最先确定的操作数是4)

4

>>> 0 and 4 (0为False不需往后看,所以最先确定的操作数是0)

0

>>> False or 3 or 0 (False还要往后看,3为True不需往后看,所以最先确定的操作数是3)

3

运算符优先级

1249675-20180315095020476-894561679.png

类型转换

类型转换中,int、float转字符串用str()就行了,非常容易理解,字符串是"数字"字符串('1234')转int也好理解,但如果是字符串'a'呢?可能你会想到ASCII,用int('a')可以吗?

1249675-20180315212703762-987049758.png

结果显示不可以,所以,再恶补点知识吧!

1.十进制字符串转整数

int('12') ==12

2.十六进制字符转整数

int('a',16) == 10

例MAC地址转整数:

a='FF:FF:FF:FF:FF:FF'.split(:)

int(a[0],16) = 255

int(a[1],16) = 255

int(a[2],16) = 255

int(a[3],16) = 255

int(a[4],16) = 255

int(a[5],16) = 255

3.字符转整数

ord('a')==97

4.整数转为字符

chr(65) == 'A'

1249675-20180315213318568-488596417.png

四、循环

range()

range() 生成一个等差数列(并不是列表):

>>> for i in range(3):

... print(i)

...

0

1

2

>>> range(1, 5)

range(1, 5)

>>> list(range(1, 5))

[1, 2, 3, 4]

>>> list(range(1, 15, 3))

[1, 4, 7, 10, 13]

循环的 else 语句

可以在循环后面使用可选的 else 语句,它将会在循环完毕后执行,除非有 break 语句终止了循环。

斐波那契(Fibonacci)数列

1249675-20180315221132767-279548304.png

Python 中赋值语句执行时会先对赋值运算符右边的表达式求值,然后将这个值赋值给左边的变量。

如果要把结果输出不换行呢?print() 除了打印提供的字符串之外,还会打印一个换行符,所以每调用一次 print() 就会换一次行。可以通过参数 end 来替换换行符:

a, b = 0, 1

while b < 100:

print(b, end=' ')

a, b = b, a + b

print()

1249675-20180315222243723-1335284529.png

幂级数:e^x = 1 + x + x^2 / 2! + x^3 / 3! + ... + x^n / n! (0 < x < 1)

#!/usr/bin/env python3

x = float(input("Enter the value of x: "))

n = term = num = 1

result = 1.0

while n <= 100:

term *= x / n

result += term

n += 1

if term < 0.0001:

break

print("No of Times= {} and Sum= {}".format(n, result))

打印图形

print("#" * 50)字符串若是乘上整数 n,则返回由 n 个此字符串拼接起来的新字符串。如要打印出下图:

1249675-20180315223533099-502841180.png

row = int(input("Enter the number of rows: "))

n = row

while n >= 0:

x = "*" * n

y = " " * (row - n)

print(y + x)

n -= 1

五、数据结构

列表

列表可以写作中括号之间的一列逗号分隔的值。列表的元素不必是同一类型,通过索引来访问列表中的每一个值,列表允许修改元素,允许嵌套。

a.append() 添加元素到列表的末端

a.insert(0, 1) 在列表索引 0 位置添加元素 1

a.count(s) 返回列表中 s 元素出现的次数。

a.remove(s) 移除列表中s元素

a.pop(n) 返回索引为n的元素并把它从列表中删除,无参数时默认最后一个元素

del a[n] 删除索引为n的列表元素

a.reverse() 反转整个列表

a.sort() 给列表排序,排序的前提是列表的元素是可比较的

a.extend(b) 将b列表的所有元素添加到a列表末尾,注意是添加 b 的元素而不是 b 本身

1249675-20180316111600296-159811275.png

1249675-20180316111601880-1734589913.png

思考:如果列表中有相同的元素,用remove删除的是前面那个还是后面那个,亦或是全删除呢?实践一下呗!

1249675-20180317150032586-541003906.png

列表推导式由包含一个表达式的中括号组成,表达式后面跟随一个 for 子句,之后可以有零或多个 for 或 if 子句。结果是一个列表,由表达式依据其后面的 for 和 if 子句上下文计算而来的结果构成。以下两种方式等同:

1249675-20180316123259108-671886231.png

列表推导式也可以嵌套:

>>> a=[1,2,3]

>>> z = [x + 1 for x in [x ** 2 for x in a]]

>>> z

[2, 5, 10]

如果在遍历列表(或任何序列类型)的同时获得元素索引值,可以使用 enumerate():

>>> for i, j in enumerate(['a', 'b', 'c']):

... print(i, j)

...

0 a

1 b

2 c

同时遍历两个序列类型可以使用zip() :

>>> a = ['a', 'b']

>>> b = ['c', 'd']

>>> for x, y in zip(a, b):

... print("{} and {}".format(x, y))

元组

元组是由数个逗号分割的值组成,且为不可变类型,意味着不能在元组内删除或添加或编辑任何值。

>>> a = 'a', 'b', 'c',

>>> a

('a', 'b', 'c')

创建只含有一个元素的元组,在值后面跟一个逗号,这是因为括号()既可以表示元组,又可以表示数学公式中的小括号,这就产生了歧义。

>>> a = (123) 这样定义的将是123这个元素,而不是一个元组。

>>> a

123

>>> type(a)

>>> a = (123, )

>>> b = 321,

>>> a

(123,)

>>> b

(321,)

>>> type(a)

>>> type(b)

可以对任何一个元组执行拆封操作并赋值给多个变量,注意赋值时数量要匹配:

1249675-20180316123259098-1913140687.png

集合

集合是一个无序不重复元素的集,大括号或 set() 可以用来创建集合

>>> basket = {'apple', 'orange', 'apple', 'pear', 'orange', 'banana'}

>>> print(basket) 可以看到重复的元素被去除

{'orange', 'banana', 'pear', 'apple'}

>>> a = set('abracadabra')

>>> b = set('alacazam')

>>> a

{'a', 'r', 'b', 'c', 'd'} a 去重后的字母

>>> a - b a 有而 b 没有的字母

>>> a | b 存在于 a 或 b 的字母

>>> a & b a 和 b 都有的字母

>>> a ^ b 存在于 a 或 b 但不同时存在的字母

>>> a.add('c')

>>> a

{'c',a', 'r', 'b', 'c', 'd'} 不同于列表的append(),在起始位置添加

字典

字典是是无序的键值对(key:value)集合,同一个字典内的键必须是互不相同的。一对大括号 {}创建一个空字典。字典中的键必须是不可变类型,比如不能使用列表作为键。

>>> data = {'kushal':'Fedora', 'kart_':'Debian', 'Jace':'Mac'}

>>> data['kart_']

'Debian'

>>> data['parthan'] = 'Ubuntu' 创建新的键值对

>>> data

{'kushal': 'Fedora', 'Jace': 'Mac', 'kart_': 'Debian', 'parthan': 'Ubuntu'}

>>> del data['kushal'] del 删除任意指定的键值对

>>> data

{'Jace': 'Mac', 'kart_': 'Debian', 'parthan': 'Ubuntu'

>>> dict((('In','Del'),('Bang','Dh'))) dict() 从包含键值对的元组中创建字典

{'In': 'Del', 'Bang': 'Dh'}

>>> for x, y in data.items(): items()获得由键和值组成的列表

... print("{} uses {}".format(x, y))

dic.clear()清空字典

dic.keys()获得键的列表

dic.values()获得值的列表

dic.copy()复制字典

dic.pop(k)删除键k

dic.get(k)获得键k的值

dic.update()更新成员,若成员不存在,相当于加入

很多时候需要往字典中的元素添加数据,使用dict.setdefault(key, default):

>>> data = {}

>>> data.setdefault('names', []).append('Ruby')

>>> data

{'names': ['Ruby']}

>>> data.setdefault('names', []).append('Python')

>>> data

{'names': ['Ruby', 'Python']}

>>> data.setdefault('names', []).append('C')

>>> data

{'names': ['Ruby', 'Python', 'C']}

切片

切片的语法表达式为[start_index : end_index : step]:

start_index表示起始索引

end_index表示结束索引

step表示步长,步长不能为0,且默认值为1

切片操作是指按照步长,截取从起始索引到结束索引,但不包含结束索引的所有元素。

python3支持切片操作的数据类型有list、tuple、string、unicode、range

切片返回的结果类型与原对象类型一致

切片不会改变原对象,而是重新生成了一个新的对象

切片的索引可分为正向和负向两种:

1249675-20180315224626553-1062573263.png

举个例子:

>>> C = ['A','B','C','D','E','F']

>>> C[0:5:1]

['A', 'B', 'C', 'D','E']

1249675-20180315224645729-16138742.png

省略 start_index 会从第一个元素开始,省略 end_index 会切到最后一个元素为止:

>>> C[2:]

['C', 'D', 'E', 'F']

步长为负数时即为逆着切,一定要保证start_index到end_index的方向与步长step的方向同向,否则会切出空的序列:

>>> C[0:3:-1]

[]

>>> C[3:0:1]

[]

数据结构举例

1.判断学生成绩是否达标:要求输入学生数量,以及各个学生物理、数学、历史三科的成绩,如果总成绩小于 120,程序打印 “failed”,否则打印 “passed”。

n = int(input("Enter the number of students: "))

data = {} 用来存储数据的字典变量

Subjects = ('Physics', 'Maths', 'History')

for i in range(1, n+1):

name = input('Enter the name of the student {}: '.format(i))

marks = []

for x in Subjects:

marks.append(int(input('Enter marks of {}: '.format(x))))

data[name] = marks

for x, y in data.items():

total = sum(y)

print("{}'s total marks {}".format(x, total))

if total < 120:

print(x, "failed :(")

else:

print(x, "passed :)")

运行如下:

1249675-20180316135730839-502568461.png

2.用以下代码解决矩阵问题:

n = int(input("Enter the value of n: "))

print("Enter values for the Matrix A")

a = []

for i in range(n):

a.append([int(x) for x in input().split()])

print(a)

1249675-20180316140001545-2055567092.png

其实这里不太理解为什么最后结果为列表嵌套列表(str.split(str="", num=string.count(str)),str -- 分隔符,默认为所有的空字符,包括空格、换行(\n)、制表符(\t)等,num -- 分割次数),而且以为这是生成 n × n 的矩阵,所以进行以下实践:

1249675-20180316194548214-2142195682.png

1249675-20180316194550539-1106288049.png

可以看出,split()最后拆成的是列表,以换行符结束一次循环,并不是生成n × n 的矩阵。相对于split(),join()使用指定字符连接多个字符串,它需要一个包含字符串元素的列表作为输入,然后连接列表内的字符串元素:

>>> "-".join("GNU/Linux is great".split())基于空格分割字符串(列表),再用 "-" 连接

'GNU/Linux-is-great'

六、字符串

三引号(triple quotes)

python三引号允许一个字符串跨多行,字符串中可以包含换行符、制表符以及其他特殊字符。

>>> h = '''hi

Jspo'''

>>> hi

'hi\nJspo'

>>> print hi

hi

Jspo

三引号让程序员从引号和特殊字符串的泥潭里面解脱出来,自始至终保持一小块字符串的格式是所谓的WYSIWYG(所见即所得)格式的。一个典型的用例是,当需要一块HTML或者SQL时,这时用字符串组合,特殊字符串转义将会非常的繁琐。

此外,在 Python 里使用文档字符串(docstrings)来说明如何使用代码:

def longest_side(a, b):

"""

Function to

"""

return True

字符串常用操作

string.title() 返回字符串的标题版本,即单词首字母大写其余字母小写

string.upper() 返回字符串全部大写版本

string.lower() 返回字符串全部小写版本

string.swapcase() 返回字符串大小写交换后的版本

string.isalnum() 检查所有字符是否为字母数字

string.isalpha() 检查字符串之中是否只有字母

string.isdigit() 检查字符串是否所有字符为数字

strip(chars)用来剥离字符串首尾中指定的字符,不指定参数则默认剥离掉首尾的空格和换行符。用 lstrip(chars) 或 rstrip(chars) 只对字符串左或右剥离:

>>> s = "www.foss.in"

>>> s.lstrip("cwsd.") 删除在字符串左边出现的'c','w','s','d','.'字符

'foss.in'

>>> s.rstrip("cnwdi.") 删除在字符串右边出现的'c','n','w','d','i','.'字符

'www.foss'

文本搜索

find() 能帮助找到第一个匹配的子字符串,没有找到则返回 -1。string.find(str, beg=0, end=len(string))

检测 str 是否包含在 string 中,如果 beg 和 end 指定范围,则检查是否包含在指定范围内,如果是返回开始的索引值,否则返回-1。

s.startswith(str) 检查字符串是否以 str 开头

s.endswith(str) 检查字符串是否以 str 结尾

字符串更多操作详见:Python 字符串

例题(挑战:字符串操作)

String.txt文件内容为awe3fa8fa4aewfawijfa;fjaweawfeawawefargaefaef5awefasdfeargfasdcds2awea4afadszsdvzxefafzsdva7fasdczdvafedszv6zvczvdsf2awefafzsdccsea,请把该文件中所有的数字组成一个新的字符串,并且打印出来。

1249675-20180317150035435-1475903021.png

1249675-20180317150033746-841361968.png

注:学了后面的课程发现这个挑战自己没将文件关闭(file.close()),要养成习惯,不然记得使用 with!

七、函数

def 函数名(参数列表):

函数体

不带表达式的return相当于返回 None。

参数传递

在 python 中,类型属于对象,变量是没有类型。如a=[1,2,3]和a="Jspo",[1,2,3] 是 List 类型,"Jspo" 是 String 类型,而变量 a 是没有类型,仅仅是一个对象的引用(一个指针),可以是指向 List 类型对象,也可以是指向 String 类型对象。

在 python 中,strings, tuples, 和 numbers 是不可更改的对象,而 list,dict 等则是可以修改的对象。

不可变类型:变量赋值 a=5 后再赋值 a=10,这里实际是新生成一个 int 值对象 10,再让 a 指向它,而 5 被丢弃,不是改变a的值,相当于新生成了a

可变类型:变量赋值 la=[1,2,3,4] 后再赋值 la[2]=5 则是将 list la 的第三个元素值更改,本身la没有动,只是其内部的一部分值被修改了

python 函数的参数传递:

不可变类型:类似值传递,传递的只是a的值,没有影响a对象本身(加global变为全局变量)

可变类型:类似引用传递

参数类型

必需参数:以正确的顺序传入函数,调用时的数量必须和声明时的一样

关键字参数:形如 keyword = value,使用关键字参数允许函数调用时参数的顺序与声明时不一致,因为 Python 解释器能够用参数名匹配参数值

1249675-20180317095324021-994095956.png

默认参数:调用函数时,如果没有传递参数,则会使用默认参数,默认参数必须放在最后。如上图如果调用者未给出 b、c 的值,那么它们的值默认为5和10

不定长参数:需要一个函数能处理比当初声明时更多的参数。这些参数叫做不定长参数,声明时不会命名

对不定长参数再说几句:加了星号(*)的变量名会存放所有未命名的变量参数,不能存放dict。加了星号(**)的变量名会存放所有未命名的变量参数(如果在函数调用时没有指定参数,它就是一个空元)。举个例子:

def multiple(arg, *args, **dictargs):

print("arg: ", arg)

#打印args

for value in args:

print("other args:", value)

#打印dict类型的不定长参数 args

for key in dictargs:

print("dictargs:" + key + ":" + str(dictargs[key]))

if __name__ == '__main__':

multiple(1,'a',True, name='Amy',age=12)

1249675-20180317105747877-529282585.png

高阶函数

map 接受一个函数和一个序列(迭代器)作为输入,然后对序列(迭代器)的每一个值应用这个函数,返回一个序列(迭代器),其包含应用函数后的结果。

>>> lst = [1, 2]

>>> def s(num):

... return num * num

...

>>> print(list(map(s, lst)))

[1, 4]

1249675-20180317110121606-298224288.png

注:千万别忘了map前加list!

八、文件处理

常见操作

1249675-20180317110740056-786427820.png

使用 open() 函数打开文件,需要两个参数,第一个参数是文件路径或文件名,第二个是文件的打开模式:

"r",以只读模式打开,你只能读取文件但不能编辑/删除文件的任何内容

"w",以写入模式打开,如果文件存在将会删除里面的所有内容,然后打开这个文件进行写入

"a",以追加模式打开,写入到文件中的任何数据将自动添加到末尾

例题

例1:拷贝给定的文本文件到另一个给定的文本文件:

import sys

if len(sys.argv) < 3:

print("Wrong parameter")

print("./copyfile.py file1 file2")

sys.exit(1)

f1 = open(sys.argv[1])

s = f1.read()

f1.close()

f2 = open(sys.argv[2], 'w')

f2.write(s)

f2.close()

1249675-20180317120444598-91509845.png

sys模块:sys.argv 包含所有命令行参数。

sys.argv 的第一个值是命令自身的名字:

import sys

print("First value", sys.argv[0])

print("All values")

for i, x in enumerate(sys.argv):

print(i, x)

1249675-20180317120405825-565462455.png

enumerate(iterableobject)可以同时得到索引位置和对应值。

例2:对任意给定文本文件中的制表符、行、空格进行计数。

import os

import sys

def parse_file(path):

fd = open(path)

i = 0

spaces = 0

tabs = 0

for i,line in enumerate(fd):

spaces += line.count(' ')

tabs += line.count('\t')

# 现在关闭打开的文件

fd.close()

# 以元组形式返回结果

return spaces, tabs, i + 1

def main(path):

if os.path.exists(path):

spaces, tabs, lines = parse_file(path)

print("Spaces {}. tabs {}. lines {}".format(spaces, tabs, lines))

return True

else:

return False

if __name__ == '__main__':

if len(sys.argv) > 1:

main(sys.argv[1])

else:

sys.exit(-1)

sys.exit(0)

小Tips:

如果要统计文件的行数,可以用count = len(open(filepath, 'r').readlines()),虽然简单,但是可能比较慢,当文件比较大时甚至不能工作。因此可以利用enumerate():

count = 0

for index, line in enumerate(open(filepath,'r')):

count += 1

此外,使用 with 语句处理文件对象会在文件用完后会自动关闭,就算发生异常也没关系。它是 try-finally 块的简写:

with open('sample.txt') as f:

for line in f:

print(line, end = '')

九、异常

在 Python3 中使用 Python2 独有的语法就会发生 SyntaxError

当有人试图访问一个未定义的变量则会发生 NameError

当操作或函数应用于不适当类型的对象时引发TypeError,一个常见的例子是对整数和字符串做加法

try--except

首先,执行 try 子句 ,如果没有异常发生,except 子句 在 try 语句执行完毕后就被忽略了。

如果在 try 子句执行过程中发生了异常,那么该子句其余的部分就会被忽略。

如果异常匹配于 except 关键字后面指定的异常类型,就执行对应的 except 子句。然后继续执行 try 语句之后的代码。

如果发生了一个异常,在 except 子句中没有与之匹配的分支,它就会传递到上一级 try 语句中。

如果最终仍找不到对应的处理语句,它就成为一个 未处理异常,终止程序运行,显示提示信息。

except可以处理一个专门的异常,也可以处理一组圆括号中的异常,如果except后没有指定异常,则默认处理所有的异常。

raise

raise 语句抛出一个异常。如"挑战:玩转函数"中要求用户能够通过命令行输入分钟数,程序需要打印出相应的小时数和分钟数。如果用户输入的是一个负值,程序需要报错 ValueError,在屏幕上打印出ValueError: Input number cannot be negative 提示用户输入的值有误。

import sys

def ToHours(time):

print("{} H, {} M".format(*divmod(time, 60)))

time =int (sys.argv[1])

if time < 0:

try:

raise ValueError

except ValueError:

print("ValueError: Input number cannot be negative")

else:

ToHours(time)

1249675-20180317140535948-641221427.png

finally

不管有没有发生异常,finally 子句在程序离开 try 后都一定会被执行。当 try 语句中发生了未被 except 捕获的异常(或者它发生在 except 或 else 子句中),在 finally 子句执行完后它会被重新抛出:

>>> try:

... raise KeyboardInterrupt

... finally:

... print('Goodbye, world!')

...

Goodbye, world!

KeyboardInterrupt

Traceback (most recent call last):

File "", line 2, in ?

在真实场景的应用程序中,finally 子句用于释放外部资源(文件或网络连接之类的),无论它们的使用过程中是否出错。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值