Python基础 (上)
目录
一、数据类型
string、list和tuple都属于sequence(序列)。三者都可以进行截取,索引值以0为开始值,-1为从末尾的开始位置。加号+是字符串的连接符。 星号*表示复制当前字符串,紧跟的数字为复制的次数。
1. 数字(Number)
用于存储数值,每个变量在使用前都必须赋值。数据类型是不允许改变的,这就意味着如果改变数字数据类型的值,将重新分配内存空间。
a = 5
a = b = c = 1 # 多个变量赋值
a, b, c = 1, 2, 5.6
2. String(字符串)
在Python3中,所有字符串都是Unicode字符串。( Python的注释: 单行注释以#开头, 行注释用三个单引号 '' 或三个双引号 "" 将注释括起来 )
a. 字符串截取 print (str) # 输出字符串 Hello print (str[0:-1]) # 输出第一个到倒数第二个的所有字符, Hell b. 使用反斜杠(\)转义特殊字符,在字符串前面添加一个r则不会转义 print(r"Hello\nWorld") # 不换行,直接输出Hello\nWorld print ("我叫 %s 今年 %d 岁!" % ('小明', 10)) 字符串格式化 c. python三引号允许一个字符串跨多行,字符串中可以包含换行符、制表符以及其他特殊字符。 para_str = """这是一个多行字符串的实例 多行字符串可以使用制表符TAB ( \t )。 """
3. List(列表)
列表中元素的类型可以不相同,它支持数字,字符串甚至可以包含列表(所谓嵌套)。
employee = [1, 'Amy', 23, 'China', 27000.00] company = ['ABC', 'US'] print(employee[1:3] * 2) # 从第二个开始输出到第三个元素, 输出两次 ['Amy', 23, 'Amy', 23] print(employee + company) # [1, 'Amy', 23, 'China', 27000.00, 'ABC', 'US'] employee[1:3] = ['Sandy', 18] # list元素可以改变 del employee[2] # 可以使用 del 语句来删除列表的的元素
4. Tuple(元组)
元组与字符串类似,可以把字符串看作一种特殊的元组。
a. 元组的定义 tuple = (1, 'Amy', 23, 'China', 27000.00) tup1 = () # 空元组 tup2 = (20,) # 一个元素,需要在元素后添加逗号,否则括号会被当作运算符使用,tup2 = (20)表示整数 t = 1, 2, 'a' # t[0]=1 t=(1, 2, 'a') u = t, (1, 2, 3, 4, 5) # u=((12345, 54321, 'hello!'), (1, 2, 3, 4, 5)) b. 截取 print (tuple[0:-1]) # 截取 tup3 = tup1 + tup2; # 创建一个新的元组,元组中的元素值是不允许修改的,但我们可以对元组进行连接组合 del tup #元组中的元素值是不允许删除的,但我们可以使用del语句来删除整个元组 c. 函数应用 def test1(a,b): #函数返回多个值的时候,是以元组的方式返回的。 return (a,b) def test2(*args): #python中的函数还可以接收可变长参数,参数名以*开头,该参数的类型也是元组 return args
5. Set(集合)
集合(set)是一个无序不重复元素的序列。基本功能是进行成员关系测试和删除重复元素。可以使用大括号{}或者set()函数创建集合。
注意:创建一个空集合必须用set()而不是{},因为{}是用来创建一个空字典。
a. 成员测试 student = {'Tom', 'Jim', 'Mary', 'Tom', 'Jack', 'Rose'} if('Rose' in student) : print('Rose 在集合中') b. 集合计算 s1 = set('abracadabra'); s2 = set('alacazam') print(s1 - s2) # s1和s2的差集 {'b', 'd', 'r'} |表示并集 &表示交集 ^表示s1和s2中不同时存在的元素
6. Dictionary(字典)
字典(dictionary)是Python中另一个非常有用的内置数据类型。列表是有序的对象结合,字典是无序的对象集合。字典当中的元素是通过键来存取的,键(key)必须使用不可变类型。创建空字典使用{}
dict = {'Name': 'Amy', 'Age': 18} dict['Age'] = 20; # 更新 Age dict.clear() # 清空字典 del dict # 删除字典
判断对象类型
type(a) # <class 'int'> isinstance(a, int) # True 区别:type()不会认为子类是一种父类类型。isinstance()会认为子类是一种父类类型。 class A: pass # 如果没有内容,可以写pass,但是如果不写pass就会语法错误 class B(A): pass print(type(B(), A) # False print(isinstance(B(), A) # True
遍历字典
fruit = {'a': 'apple', 'b': 'banana'} for k, v in fruit.items(): print(k, v)
6. 列表的变形
# 列表基本方法 ls = ['a', 'b', 'c'] ls.count('a') # 1 ls.insert(1, 'a1') # ['a', 'a1', 'b', 'c'] ls.append('d') # ['a', 'a1', 'b', 'c', 'd'] ls.index('b') # 2 ls.remove('a1') # ['a', 'b', 'c', 'd'] ls.reverse() # ['d', 'c', 'b', 'a'] ls.sort() # ['a', 'b', 'c', 'd'] #遍历列表 for i, v in enumerate(['a', 'b', 'c']): print(i, v) # 使用zip()组合同时遍历两个或更多的序列 for q, a in zip(questions, answers): print('What is your {0}? It is {1}.'.format(q, a)) #反向遍历一个序列, 正向使用sorted for i in reversed(range(1, 10, 2)): print(i) #9 7 5 3 1 # 将列表当做堆栈使用(后进先出) stack = ['a', 'b', 'c'] stack.append('d') # ['a', 'b', 'c', 'd'] stack.pop() # ['a', 'b', 'c'] # 将列表当作队列使用(先进先出) from collections import deque queue = deque(['a', 'b', 'c']) queue.append('d') # deque(['a', 'b', 'c', 'd']) queue.popleft() # deque(['b', 'c', 'd']) 从头部弹出较慢,所有元素都要移位 # 列表推导式 # 使用for循环对列表中的每个元素进行表达式计算,从而生成新的列表 fruit = [' banana', ' appke '] [f.strip() for f in fruit] #['banana', 'apple'] vec = [2, 4, 6] [3*x for x in vec] # [6, 12, 18] [[x, x**2] for x in vec]# [[2, 4], [4, 16], [6, 36]] [3*x for x in vec if x > 3] #[12, 18] vec2 = [4, 3, -9]; [x*y for x in vec1 for y in vec2] #[8, 6, -18, 16, 12, -36, 24, 18, -54] [str(round(355/113, i)) for i in range(1, 6)] # ['3.1', '3.14', '3.142', '3.1416', '3.14159'] # 嵌套列表解析 # 将3X4的矩阵列表转换为4X3列表 matrix = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]] # 方法1 [[row[i] for row in matrix] for i in range(4)] # 方法2 transposed = [] for i in range(4): transposed.append([row[i] for row in matrix]) # del 语句 ls = ['a', 'b', 'c', 'd', 'e', 'f'] del ls[0] # ['b', 'c', 'd', 'e', 'f'] del ls[2:4] # ['b', 'c', 'f'] del ls[:] # [] del ls # [] # 字典推导 {x: x**2 for x in (2, 4, 6)} # {2: 4, 4: 16, 6: 36}
二、运算符
1. 算术运算符: + - * / % **(求幂) //(整除,返回商的整数部分)
- 5 / 2 = 2.5
- 5 // 2 = 2
- 5 ** 2 = 25
2. 位运算符: & | ^(异或) ~(取反) << (左移) >> (右移)
3. 逻辑运算符: and or not(非)
4. 成员运算符: in 、not in
5. 身份运算符: is 、is not
is 用于判断两个变量引用对象是否为同一个, == 用于判断引用变量的值是否相等。
a = 20 b = 20 if ( a is b ): # True print ("a 和 b 有相同的标识") if ( id(a) == id(b) ): # True print ("a 和 b 有相同的标识") a = [1, 2, 3] b = a # a is b, a和b指向同一对象 b = a[:] # a is not b, a和b指向不同对象
三、条件和循环控制语句
条件控制 def fab(n): if n<1: print('输入有误!') return -1 elif n==1 or n==2: return 1 else: return fab(n-1)+fab(n-2) 循环控制 # Fibonacci series: 斐波纳契数列 1,1,2,3,5,8 a, b = 0, 1 while b < 10: print(b, end=',') a, b = b, a+b sequence = [1,1,2,3,5,8] for item in sequence: print(item) for index, item in enumerate(sequence): print(index, item) # 求整数1-100的和 sum = 0 for i in range(0,101): # 或 for i in range(101) sum += i print(sum)
迭代器
迭代是Python最强大的功能之一,是访问集合元素的一种方式。迭代器对象从集合的第一个元素开始访问,迭代器只能往前不会后退。迭代器有两个基本的方法:iter() 和 next()。字符串,列表或元组对象都可用于创建迭代器。
1.使用for循环迭代 list=[1,2,3,4] it = iter(list) # 创建迭代器对象 for x in it: print (x, end=" ") 2.使用next()函数迭代 list=[1,2,3,4] it = iter(list) # 创建迭代器对象 while True: try: print (next(it)) except StopIteration: sys.exit()
生成器
在 Python 中,使用了 yield 的函数被称为生成器(generator)。生成器是一个返回迭代器的函数,每次遇到 yield 时函数会暂停并保存当前所有的运行信息,并在下一次执行 next() 返回 yield的值, 方法时从当前位置继续运行。
import sys def fibonacci(n): # 生成器函数 - 斐波那契 a, b, counter = 0, 1, 0 while True: if (counter > n): return yield a a, b = b, a + b counter += 1 f = fibonacci(10) # f是一个迭代器,由生成器返回生成。只需返回迭代器,而不用返回整个斐波那契列表 while True: try: print (next(f), end=" ") # 使用迭代器 except StopIteration: sys.exit()
四、函数
函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段。函数能提高应用的模块性,和代码的重复利用率。Python提供了许多内建函数,你也可以自定义函数。
1. 可更改(mutable)与不可更改(immutable)对象
在python中,string、tuple和number是不可更改的对象,重新赋值不会修改原来的对象,而是生成一个新的对象。而list,dict等则是可以修改的对象。python函数的参数传递类似c++的参数传递,如果传的是不可变类型,则函数中的任何操作不会影响传递的对象本身。如果是可变类型如列表、字典,则类似c++的引用传递,可以在函数中修改对象的值。
1.不可变类型参数 def changeInt( a ): a = 10 b = 2 changeInt(b) print( b ) # 结果是 2 2.可变类型参数 def changeList( mylist ): mylist[1]=5 return mylist = [1,2,3]; changeList( mylist ); print (mylist) # 结果是[1,5,3]
2. 函数调用
1.关键字参数: 函数调用时使用参数的顺序与声明时不一致,因为 Python 解释器能够用参数名匹配参数值 fibonacci ( n = 10 ) 2.默认参数:函数定义中设置默认参数值,如果调用时没有传递参数,则会使用默认参数。默认参数要放在最后面,否则会报错。 def printinfo(name, age=35): print (name, age) 3.不定长参数 def printinfo(*args): print (args) printinfo(1, 'Amy', 18) 4.函数参数 def printInfo () : print ("Hello, world!") def execute(f): f() # 执行函数 execute(printInfo)
3. 匿名函数
python 使用 lambda 来创建匿名函数。所谓匿名,即不再使用 def 语句这样标准的形式定义一个函数。lambda的主体是一个表达式,而不是一个代码块。lambda 函数拥有自己的命名空间,且不能访问自己参数列表之外或全局命名空间里的参数。匿名函数也能使用关键字参数和默认参数。
sum = lambda arg1, arg2: arg1 + arg2; print ("sum = ", sum( 10, 20 ))
4. 变量作用域
Python 中只有模块,类以及函数(def、lambda)才会引入新的作用域,其它的代码块(如 if/else、for/while等)是不会引入新的作用域的,即这些语句内定义的变量,外部也可以访问。Python的作用域一共有4种,代码中的变量以 L –> E –> G –>B 的规则查找,即在局部找不到,便会去闭包找,然后是全局,再者去内建中找。
- L (Local) 局部作用域
- E (Enclosing) 闭包函数外的函数中
- G (Global) 全局作用域
- B (Built-in) 内建作用域
内置作用域是通过一个名为builtin的标准模块来实现的,但是这个变量名自身并没有放入内置作用域内,所以必须导入这个文件才能够使用它。在Python3.0中,可以使用以下的代码来查看到底预定义了哪些变量:
>>> import builtins
>>> dir(builtins)
x = int(2.9) # 内建作用域 g_count = 0 # 全局作用域,全局变量可以在整个程序范围内访问 def outer(): o_count = 1 # 闭包函数外的函数中 def inner(): i_count = 2 # 局部作用域,局部变量只能在其声明的函数内使用
global 和 nonlocal关键字
函数中修改全局变量 num = 1 def fun1(): global num # 需要使用 global 关键字声明 print(num) num = 123 print(num) fun1() 修改嵌套作用域(enclosing 作用域,外层非全局作用域)中的变量则需要 nonlocal 关键字 def outer(): num = 10 def inner(): nonlocal num # nonlocal关键字声明 num = 100 print(num) inner() print(num) outer()
五、模块
模块是一个包含所有你定义的函数和变量的文件(.py文件)。模块可以被别的程序引入,以使用该模块中的函数等功能。这也是使用 python 标准库的方法。
import 语句
一个模块只会被导入一次,不管你执行了多少次import。当我们使用import语句的时候,Python解释器通过python搜索路径查找相应模块。搜索路径是在Python编译或安装的时候确定的,可以使用sys.path查看。
# calculator.py文件 def calc(a, b): print('a + b = ', a + b) return # test.py文件 import calculator # 导入模块 calculator.calc(1, 2) # 调用模块里的函数 import calculator calc1 = calculator.calc # 经常使用一个函数时,可以把它赋给一个本地的名称 calc1(1, 2) from calculator import calc # 导入指定部分(函数或变量) calc(1, 2) from calculator import * # 导入所有内容 calc(1, 2)
__name__属性
每个模块都有一个__name__属性,当其值是'__main__'时,表明该模块自身在运行,否则是被引入。如果我们想在模块被引入时,模块中的某一程序块不执行,我们可以用__name__属性来使该程序块仅在该模块自身运行时执行。
# using_name.py if __name__ == '__main__': print('程序自身在运行') else: print('我来自另一模块,被引入时不执行') >>> python using_name.py # 输出: 程序自身在运行 >>> import using_name # 输出: 我来自另一模块,被引入时不执行
dir() 函数
内置的函数 dir() 可以找到模块内定义的所有名称,且以一个字符串列表的形式返回。如果没有给定参数,那么 dir() 函数会罗列出当前定义的所有名称。
import calculator print(dir(calculator)) # ['__builtins__', '__doc__', '__file__', '__name__', '__package__', 'calc'] print(dir()) # ['__builtins__', '__doc__', '__file__', '__name__', '__package__', 'calculator']
标准模块
Python 本身带着一些标准的模块库,模块 sys 内置在每一个 Python 解析器中。变量 sys.ps1 和 sys.ps2 定义了主提示符和副提示符所对应的字符串。
Python包
包是一种管理 Python 模块命名空间的形式,采用"点模块名称"。比如一个模块的名称是 A.B, 那么他表示一个包 A中的子模块 B 。在导入一个包的时候,Python 会根据 sys.path 中的目录来寻找这个包中包含的子目录。目录只有包含一个叫做 __init__.py 的文件才会被认作是一个包,最简单的情况,放一个空的 :file:__init__.py就可以了。当然这个文件中也可以包含一些初始化代码或者为 __all__变量赋值。
sound/ #顶层包 __init__.py #初始化 sound 包 formats/ #文件格式转换子包 __init__.py wavread.py wavwrite.py
从一个包中导入*
Windows是一个大小写不区分的系统,很难知道 ECHO.py 的文件导入为模块 echo 还是 Echo 甚至 ECHO。然而包定义文件 __init__.py 存在一个叫做 __all__ 的列表变量,在使用 from package import * 的时候就把这个列表中的所有名字作为包内容导入。通常我们并不主张使用*这种方法来导入模块,因为这种方法经常会导致代码的可读性降低。使用_all_可以在sound/formats/__init__.py中包含如下代码:
__all__ = ["wavread", "wavwrite"]
六、输入与输出
1. 控制台输入
str = input("请输入:"); print ("你输入的内容是: ", str)
2. 格式化输出
(1) str.format() 用于设置多样化的输出格式
# 参数位置 print('{} and {}'.format('apple', 'banana')) # apple and banana, 默认顺序 print('{0} and {1}'.format('apple', 'banana')) # apple and banana, 指定参数位置 print('{1} and {0}'.format('apple', 'banana')) # banana and apple print('{name}网址: {site}'.format(name='百度', site='www.baidu.com')) # 百度网址:"www.baidu.com", 关键字参数 print('fruits: {0}, {1} and {other}'.format('apple', 'banana', other='pear')) # 函数符号,!a表示使用ascii(), !s使用str(), !r'使用repr() print('常量 PI 的值近似为: {!r}'.format(math.pi)) # 常量 PI 的值近似为: 3.141592653589793 # 保留小数点 print('常量 PI 的值近似为: {0:.3f}'.format(math.pi)) # 常量 PI 的值近似为: 3.142 ,保留到小数点后三位 # %操作符也可以实现字符串格式化,但是老的格式化方式,应该更多的使用 str.format(). print('常量 PI 的值近似为:%5.3f' % math.pi) # 常量 PI 的值近似为: 3.142, # 对齐方式 table = {'apple': 1, 'banana': 2, 'pear': 3} for name, number in table.items(): print('{0:10} ==> {1:10d}'.format(name, number)) # ':' 后传入一个整数, 设置字段输出宽度 # 格式化时使用变量名而非位置 print('banana: {0[banana]:d}; apple: {0[apple]:d}; pear: {0[pear]:d}'.format(table)) # 'banana:2; apple:1; pear:3 print('apple: {apple:d}; banana: {banana:d}; pear: {pear:d}'.format(**table)) # table 变量前使用 '**' 来实现相同的功能
(2) 将值转成字符串
str() : 函数返回一个用户易读的表达形式。 repr() : 产生一个解释器易读的表达形式。
s = 'Hello, World' str(s) # 'Hello, World' repr(s) # "'Hello, World'" repr('hello, World\n') # 'hello, World\n' , repr()可以转义字符串中的特殊字符 repr((1, 'desc', ('Hello', 'World'))) # repr()的参数可以是Python的任何对象 for x in range(1, 11): print(repr(x).rjust(2)) # rjust 右对齐, 将字符串靠右, 并在左边填充空格。 类似的方法有 ljust() 和 center() '-3.14'.zfill(7) #'-003.14'