容器内容一:列表 例子1:[]表示,列表值是一组用逗号隔开的有序值,可传递给变量 >>> spam = ['cat', 'bat', 'rat'] >>> spam ['cat', 'bat', 'rat'] >>> spam, spam1, spam2 = ['cat', 'bat', 'rat'] >>> spam 'cat' >>> spam1 'bat' 例子2:如果获取列表中的某个值,用偏移量(整数)表示,0代表第一个,-1代表倒数第一个,若偏移量超出列表元素个数,会出错 若列表元素是字符串,也可以通过列表[偏移量].字符串方法 >>> biycles = ['trek', 'redline'] >>> print(biycles[0].title()) Trek 例子3:列表中的值也可以是列表,若想访问可通过双重下标 >>> spam =[['cat', 'bat'], [10, 20, 30, 40]] >>> spam[0] ['cat', 'bat'] >>> spam[0][1] 'bat' 例子4:用[start:end:step]来获取列表的子列表,子列表结束偏移量为end-1,若start省略,默认从0开始,若end省略,默认在列表长度-1结束 >>> spam = ['cat', 'bat', 'rat', 'elephant'] >>> spam[0:4] ['cat', 'bat', 'rat', 'elephant'] >>> spam[1:3] ['bat', 'rat'] >>> spam[0:-1] ['cat', 'bat', 'rat'] 例子4.1 遍历切片 players = ['charles', 'martina', 'michael', 'florence', 'eli'] print('Here are the first three players on my team:') for player in players[:3]: print(player.title()) 例子4.2 若想要复制一个列表,可以通过[:] 切片的方式复制一个原列表副本 例子5:利用列表偏移量和赋值=可以改变列表中某个位置的值 例子6:len()函数可以获取到列表的长度,参数是列表变量或者列表 例子7:通过+来连接2个列表形成一个新列表,通过 列表*数字 的形式可以将列表复制 >>> [1, 2, 3] + ['A', 'B', 'C'] [1, 2, 3, 'A', 'B', 'C'] >>> ['X', 'Y', 'Z']*2 ['X', 'Y', 'Z','X', 'Y', 'Z'] 例子8:通过del语句来删除列表中某个位置的元素,其他列表值元素偏移量自动向前 >>> spam = ['cat', 'bat', 'rat', 'elephant'] >>> del spam[2] >>> spam ['cat', 'bat', 'elephant'] 例子9:列表的特点和优势:由于列表在一个结构里同时包含多个元素,可以利用这种特点,将一些操作同时进行,而不需要多条程序重复完成 将多个变量通过列表的形式变成1个变量 catNames = [] while True: print('Enter the name of cat' + str(len(catNames) + 1) + '(Or enter nothing to stop.):') name = input() if name == '': break catNames = catNames + [name] print('The cat names are:') for name in catNames: print(' ' + name) 例子10:既然列表的特点就是同时含有多个值,那列表可用于循环 >>> for i in [0, 1, 2, 3]: print(i) 注意:一个常见的python技巧,是在for循环中使用range(len(someList)),迭代列表中的每一个下标 >>> supplies = ['pens', 'staplers', 'flame-throwers', 'binders'] >>> for i in range(len(supplies)): print('Index' + str(i) + 'in supplies is:' + supplies[i]) 例子11:通过in 或者 not in来判断某一个值是否在列表里,输出布尔值 myPets = ['Zophie', 'Pooka', 'Fat-tail'] print('Enter a pet name:') name = input() if name not in myPets: print('I do not have a pet named' + name) else: print(name + ' is my pet.') 例子12:列表的方法 1. index(参数),用于查找列表中值,参数是列表中的某一个值,若参数在列表中,返回此值的偏移量;若参数不在列表中,出错。注意用法:列表.index(参数) >>> spam = ['hello', 'hi', 'howdy', 'heyas'] >>> spam.index('hello') 0 注意:如果列表中存在重复的值,就返回第一次出现的下标 >>> spam = ['Zophie', 'Pooka', 'Fat-tail', 'Pooka'] >>> spam.index('Pooka') 1 2. append(参数)和insert(参数)方法用于往列表中添加新值,append(参数)将参数添加到列表末尾;insert(参数1,参数2)方法可以在列表任意下标处插入一个值 insert方法的第一个参数是新值的偏移量,第二个参数是要插入的新值。 >>> spam = ['cat', 'dog', 'bat'] >>> spam.append('moose') >>> spam ['cat', 'dog', 'bat', 'moose'] >>> spam = ['cat', 'dog', 'bat'] >>> spam.insert(1, 'chicken') >>> spam ['cat', 'chicken', 'dog', 'bat'] 这里要注意,代码的使用,因为append()和insert()都不会将spam的新值作为其返回值,实际上,append()和insert()的返回值是None,所以列表被当场修改了 另外需要注意的是append()和insert()方法是列表方法,只能在列表上调用,不能在其他值上调用。 3. pop(索引) 删除列表中索引位置的元素,并返回该元素;若没有参数,默认删除最后一个元素。 >>> motorcycles = ['honda', 'yamaha', 'suzuki'] >>> last_owned = motorcycles.pop() >>> print('The last motorcycle I owned was a ' + last_owned.title() + '.') The last motorcycle I owned was a Suzuki. >>> motorcycles = ['honda', 'yamaha', 'suzuki'] >>> first_owned = motorcycles.pop(0) >>> print('The first motorcycle I owned was a ' + first_owned.title() + '.') The first motorcycle I owned was a Honda. 例子13.前面介绍了一种del语句结合偏移量删除列表值的方法,另一种方法remove()从列表中删除值,若值重复,只删除第一个,注意方法:列表/列表变量.remove(值) >>> spam = ['cat', 'bat', 'rat', 'elephant'] >>> spam.remove('bat') >>> spam ['cat', 'rat', 'elephant'] 总结:如果你不确定该使用del 语句还是pop() 方法,下面是一个简单的判断标准:如果你要从列表中删除一个元素,且不再以任何方式使用它,就使用del 语句;如果你要在删除元 素后还能继续使用它,就使用方法pop() 。 例子14.sort()方法将列表中的值排序,针对的是数值的列表或者字符串的列表,sort()方法和append()、insert()方法类似,都是直接对列表进行排序,而不是靠返回值 sort()在没有参数的情况下,默认对数值从小到大,对字母按顺序(ASCII字符顺序)(大写在小写之前)进行排序;若想要逆向排序,参数为sort(reverse=True) 注意用法,列表/列表变量/字符串/字符串变量.sort(),不能对既有数字又有字符串的列表排序 如果需要按照普通的字典顺序来排序,需要将参数设置为key=str.lower >>> spam = ['a', 'A', 'z', 'Z'] >>> spam.sort() >>> spam ['A', 'Z', 'a', 'z'] >>> spam.sort(key = str.lower) >>> spam ['a', 'A', 'z', 'Z'] 例子14.1 因为sort()函数是对列表元素进行直接排序并且直接把原列表永久修改掉,若只想暂时对列表排序,并不想修改原来列表顺序,可以通过 sorted()函数 cars = ['bmw', 'audi', 'toyota', 'subaru'] print('Here is the original list:') print(cars) print('\nHere is the sorted list:') print(sorted(cars)) print('\nHere is the original list again:') print(cars) Here is the original list: ['bmw', 'audi', 'toyota', 'subaru'] Here is the sorted list: ['audi', 'bmw', 'subaru', 'toyota'] Here is the original list again: ['bmw', 'audi', 'toyota', 'subaru'] 例子14.2 若要反转列表中的元素,可以使用方法 列表.reverse(),直接对原列表元素顺序进行反转 cars = ['bmw', 'audi', 'toyota', 'subaru'] print(cars) cars.reverse() print(cars) ['bmw', 'audi', 'toyota', 'subaru'] ['subaru', 'toyota', 'audi', 'bmw'] 例子14.3 遍历列表中所有元素,使用 for 变量 in 列表: 函数体 循环, 例子15. list()函数用于将其他类型的转换成列表类型 例子15.1 使用range(start,end,step)可以用来创建数字列表 >>> numbers = list(range(1,6)) >>> print(numbers) [1, 2, 3, 4, 5] >>> even_numbers = list(range(2,11,2)) >>> print(even_numbers) [2, 4, 6, 8, 10] >>> squares = [] >>> for value in range(1,11): square = value**2 squares.append(square) >>> print(squares) [1, 4, 9, 16, 25, 36, 49, 64, 81, 100] 例子15.2 有几个专门处理数字列表的函数 >>> digits = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0] >>> min(digits) 0 >>> max(digits) 9 >>> sum(digits) 45 例子15.3 前面介绍的生成列表squares 的方式包含三四行代码,而列表解析让你只需编写一行代码就能生成这样的列表。列表解析 将for 循环和创建新元素的代码合并成一行,并自动 附加新元素 >>> squares = [value**2 for value in range(1,11)] >>> print(squares) [1, 4, 9, 16, 25, 36, 49, 64, 81, 100] 例子16. 再重新总结一下Python中引用的概念 16.1 1)不可变数据类型(整型、字符串、元组)赋值给变量的时候,是给的值,并非引用,彼此相互独立,不受影响 2)可变数据类型(列表、字典)赋值给变量的时候,是复制的引用,彼此并非相互独立,一个变量的更改影响相关变量 3)引用到底是一个什么概念,引用就类似于python后台的一个ID值,指向一个实际的可能是同一个列表或字典 >>> spam = 42 >>> cheese = spam >>> spam = 100 >>> spam 100 >>> cheese 42 当两个变量指向同一个列表的时候,变量包含的是引用,而不是列表值本身。改变其中一个引用的列表,另一个含有相同引用也会被改变 >>> spam = [0, 1, 2, 3, 4, 5] >>> cheese = spam >>> cheese[1] = 'Hello' >>> spam [0, 'Hello', 2, 3, 4, 5] >>> cheese [0, 'Hello', 2, 3, 4, 5] 16.2 传递引用,要理解参数如何传递给函数,引用就特别重要。 当函数被调用时,参数的值被复制给变元,对于列表或字典,这意味着变元得到的是引用的拷贝。 def eggs(someParameter): someParameter.append('Hello') spam = [1, 2, 3] eggs(spam) print(spam) 16.3 若不想因为引用同时修改相关的变量,可通过copy模块中的copy()和deepcopy()函数复制列表或者字典的值,而非复制引用 >>> import copy >>> spam = ['A', 'B', 'C'] >>> cheese = copy.copy(spam) >>> cheese[1] = 42 >>> spam ['A', 'B', 'C'] >>> cheese ['A', 42, 'C'] 如果列表中的元素也是列表,要使用函数copy.deepcopy()来复制,会把列表中的列表元素也一同复制 小结:关于不可变数据类型字符串和可变数据类型列表,对列表的许多操作:按下标取值、切片、用于for循环、用于len()、以及用于in和not in 两者最重要的差别就是:字符串不可变,列表可变;若想改变一个字符串,要使用切片和连接,构造一个新的字符串(新的字符串变量名)。 容器二:元组 例子1. 元组数据类型与列表数据类型几乎一样(所以列表能有的方法元组也有),除了以下几点: 1)元组用()表示 >>> eggs = ('hello', 42, 0.5) >>> eggs[0] 'hello' >>> eggs[1:3] (42, 0.5) >>> len(eggs) 3 2) 元组像字符串一样,是不可改变的,包括顺序和值;也就是说元组不能让它们的值被修改、添加或者删除 eggs = ('hello', 42, 0.5) eggs[1] = 99 #这个例子是错误的代码,因为元组元素不能被修改 3)若元组只有一个元素,可以用逗号,隔开,(4,) 4) tuple()函数可以将其他类型的数据转换成元组,使用元组在告诉所有读代码的人,你不打算改变这个序列的值 容器三:字典 例子1. 字典表示方式{},方括号里的是 键-值 集合,无序,键就相当于偏移量或者索引,所以可以通过键来访问集合中的值 >>> myCat = {'size':'fat', 'color':'gray', 'disposition':'loud'} >>> myCat['size'] 'fat' 例子2. 因为字典是不排序的,所以不能像列表、元组、字符串那样切片 例子3. 要深知每一种数据类型的特点,利用其特点进行编程 birthdays = {'Alice':'Apr 1', 'Bob':'Dec 12', 'Carol':'Mar 4'} while True: print('Enter a name: (blank to quit)') name = input() if name == '': break if name in birthdays: print(birthdays[name] + 'is the birthday of ' + name) else: print('I do not have birthday information for ' + name) print('what is their birhday?') bday = input() birthdays[name] = bday print('Birthday database updated.') 例子4.字典的方法 4.1 keys(), values(), items()方法分别对应字典的键、值和键-值,用法:字典.keys(),字典.values(),字典.items() 注意:这些方法返回的并不是真正的列表,它们不能被修改,没有append()方法,其对应的数据类型分别是:dict_keys, dic_values, dic_items可以用于for循环 >>> spam = {'color':'red', 'age':42} >>> for v in spam.values(): print(v) >>> for k in spam.keys(): print(k) >>> for i in spam.items(): print(i) ('color', 'red') ('age', 42) #注意这个例子,返回的是键和值的元组 如果希望通过这些方法返回真正的列表,可以用list()函数 >>> spam = {'color':'red', 'age': 42} >>> spam.keys() dict_keys(['color', 'age']) >>>list(spam.keys()) ['color', 'age'] 也可以利用多重赋值的技巧,在for循环中将键和值赋给不同的变量 >>> spam = {'color':'red', 'age': 42} >>> for k, v in spam.items(): print('Key:' + k + 'Value: ' + str(v)) 例子5. 可以使用in或者not in来检查对应的键或者值是否存在于字典中 >>> spam = {'name': 'Zophie', 'age': 7} >>> 'name' in spam.keys() True >>> 'Zophie' in spam.values() True >>> website = {1:'google','second':'baidu',3:'facebook','twitter':4} >>> website.items() [(1, 'google'), ('second', 'baidu'), (3, 'facebook'), ('twitter', 4)] 例子5.1 遍历字典中所有的键-值 对 user_0 = { 'username': 'efermi', 'first': 'enrico', 'last': 'fermi', } for key, value in user_0.items(): print('\nKey: ' + key) print('Value: ' + value) Key: last Value: fermi Key: first Value: enrico Key: username Value: efermi 例子5.2 遍历字典中的所有键 favorite_languages = { 'jen': 'python', 'sarah': 'c', 'edward': 'ruby', 'phil': 'python', } for name in favorite_languages.keys(): print(name.title()) Jen Sarah Phil Edward favorite_languages = { 'jen': 'python', 'sarah': 'c', 'edward': 'ruby', 'phil': 'python', } if 'erin' not in favorite_languages.keys(): print('Erin, please take our poll!') Erin, please take our poll! 例子6. get()方法,在访问一个键的值之前,检查改键是否存在于字典中;两个参数:第一个参数要取得其值的键,第二个参数如果该键不存在,返回的备用值 >>> olivia = {'apples': 5, 'cups': 2} >>> 'I am bringing ' + str(olivia.get('cups', 0) + 'cups.') 'I am bringing 2 cups' >>> 'I am bringing ' + str(olivia.get('eggs', 0) + 'eggs.') 'I am bringing 0 eggs.' 例子7. 你常常需要为字典中某个键设置一个默认值,当该键没有任何值时使用它。如下代码: spam = {'name': 'Pooka', 'age': 5} if 'color' not in spam: spam['color'] = 'black' setdefault()方法提供了一种方式,在一行中完成。两个参数:第一个参数是要检查的键,第二个参数如果该键不存在时要设置的值,如果键确实存在,返回键的值 使用方法:字典.setdefault(参数1,参数2),是一个很好的确保一个键存在的方法 例子8.dict()函数可以将拥有双值子序列的序列转换成字典 容器四:集合 例子1:定义:就像舍弃了值,仅剩下键的字典一样,如果仅仅想知道某一个元素是否存在而不关心其他的,使用集合是一个非常好的选择 例子2:创建集合的方法:1){} 2)set()函数,若参数为其他类型,重复的值会被丢弃;当字典作为参数传入set()函数时,只有键被使用; >>> empty_set = set() >>> empty_set set() 解释:你可能以为空集合的表达是{},但实际上{}代表的是空字典,所以空集合的表示方式是set() 例子3:使用in测试值是否存在 例子4:合并运算符 1)交集&,或者集合函数intersection() 2)并集|,或者集合函数union() 3)差集-,或者集合函数difference(),出现在第一个集合但不出现在第二个集合 4)异或集^,或者函数symmetric_difference(),仅在两个集合中出现一次 5)<> 6)真子集, 7)>=,或者issuperset(),第一个集合的所有元素都出现在第一个集合中,超集 8)>,真超集,第一个集合包含第二个集合的所有元素且还包含其他元素 控制流语句:可以决定在什么条件下执行哪些Pyhon语句,所有控制流语句都以冒号结尾 一、在学习控制流语句之前,我们要关注一下如何表示False、True,同时也要理解,如果将分支 节点写成Python代码 1. 布尔值False、True 2. 比较操作符 ==、!=、<、>、<=、>= 3. 布尔操作符 and, or, not 二、if语句 1. 形式1: if 条件(True or False) : if子句 2.形式2: if 条件(True or False) : if子句 else: else子句 只有if语句的条件为False的时候,else子句才会被执行 3.形式3: if 条件(True or False) : if子句 elif 条件(True or False) : elif 子句 elif 条件(True or False) : elif 子句 .... 用于判断多个条件,子句中可能0个或多余0个语句被执行 4. 形式4: if 条件(True or False) : if子句 elif 条件(True or False) : elif 子句 elif 条件(True or False) : elif 子句 else: else 子句 在这种情况下,保证至少一个子句(且只有一个)会执行; 三、while循环语句,只要while的条件是True,其子代码就会一遍又一遍的执行 1. 与if的区别:if语句执行结束后,继续执行if语句后面的语句; while子句结束时,程序执行跳回while语句开始处,直到条件为False 2. while 条件: while子句 3. break语句:用于循环内部 前面讲的while循环结束的条件是条件为False,跳出循环; 若想要提前跳出循环,可以用break 语句退出循环 4. continue 语句:用于循环内部,遇到continue语句时,会马上跳回循环开始处,不执行 循环内continue后面的语句,重新跳回循环开始处 5. 如果想让一个代码块执行固定次数,可以通过for循环语句和range()函数来实现 for 变量名 in range(): for 子句 6. for-continue 语句:让for循环变量继续下一个值 continue 只能在while和for循环内部使用 7. range(),多个参数,第一个参数是for循环变量开始的值,第二个参数是上限,但不包含。 可以有第三个参数,步长。 推导式 1. 定义:推导式是从一个或者多个迭代器快速简洁地创建数据结构的一种方法。通常情况下会将循环和条件判断结合,避免语法冗长的代码。 2. 列表推导式: 1)最简单的列表推导形式: [ expression for item in iterable ] 例子1: >>> number_list = [ number for number in range(1,6) ] >>> number_list [ 1, 2, 3, 4, 5 ] 例子2: >>> number_list = [ number-1 for number in range(1, 6) ] >>> number_list [ 0, 1, 2, 3, 4 ] 2)加上条件表达式的列表推导形式: [ expression for item in iterable if condition ] 例子1: >>> a_list = [ number for number in range(1, 6) if number % 2 == 1] >>> a_list [ 1, 3, 5 ] 下面是传统的方法,注意进行类比和比较: >>> a_list = [] >>> for number in range(1,6): if number % 2 == 1: a_list.append(number) >>> a_list [1, 3, 5] 例子2: a. 传统的方式: >>> rows = range(1,4) >>> cols = range(1,3) >>> for row in rows: for col in cols: print(row, col) 1 1 1 2 2 1 2 2 3 1 3 2 b. 推导式: >>> rows = range(1,4) >>> cols = range(1,3) >>> cells = [ (row, col) for row in rows for col in cols ] #对于for row in rows和for col in cols都可以带有自己的if条件判断 >>> for cell in cells: print(cell) (1, 1) (1, 2) (2, 1) (2, 2) (3, 1) (3, 2) 或者 >>> for row, col in cells: print(row, col) 1 1 1 2 2 1 2 2 3 1 3 2 3)字典推导式 { key_expression : value_expression for expression in iterable } 类似于列表推导,字典推导也有if条件判断以及多个for循环迭代语句 >>> word = 'letters' >>> letters_counts = {letter: word.count(letter) for letter in set(word)} >>> letters_counts {'1':1, 'e':2, 't':2, 'r':1, 's':1} 4)集合推导式 {expression for expression in iterable} 同样集合推导式也有if判断语句 >>> a_set = {number for number in range(1,6) if number % 3 == 1} >>> a_set {1, 4} 5)生成器推导式 元组是没有推导式,你可能认为将列表推导式中的方括号变成圆括号就可以定义元组推导式,其实,圆括号之间的是生成器推导式, 它返回的是一个生成器对象 生成器是用来创建Python序列的一个对象,使用它可以迭代庞大的序列,且不需要在内存中创建和存储整个序列。 每次迭代生成器时,它会记录上一次调用的位置,并且返回下一个值。这一点和普通的函数是不一样的,一般函数都不记录前一次调用,而且都会在 函数的第一行开始。 |
|