1.切片L[0:3]表示从索引0开始到索引3,但不包括索引3。即索引0、1、2恰好是3个元素。如果第一个索引为0,也可以省略:>>>L=['Michael','Sarah','Tracy','Bob','Jack']>>>L[:3]['Michael','Sarah','Tracy']也可以从索引1开始取出2个元素:>>>L[1:3]['Sarah','Tracy']类似,因为Python支持L[-1]取firstlast元素,那么它也支持倒数切片,>>>L[-2:]['Bob','Jack']>>>L[-2:-1]['Bob']的索引倒数第二个元素是-1。切片操作非常有用。让我们首先创建一个0-99的序列:>>>L=list(range(100))[0,1,2,3,...,99]您可以通过切片轻松提取数字序列。例如前10个数:>>>L[:10][0,1,2,3,4,5,6,7,8,9]对于前10个数,每二取一:>>>L[:10:2][0,2,4,6,8]所有数字,每5个:>>>L[::5][0,5,10,15,20,25,30,35,40,45,50,55,60,65,70,75,80,85,90,95]甚至什么都不写,只写[:]来复制列表:>>>??L[:][0,1,2,3,...,99]元组也是一种列表,唯一的区别是元组是不可变的。因此,元组也可以通过切片来操作,但是操作的结果仍然是一个元组:>>>(0,1,2,3,4,5)[:3](0,1,2)字符串'xxx'也可以看作是一种列表,每个元素就是一个字符。因此,也可以对字符串进行切片操作,但操作的结果仍然是一个字符串:>>>'ABCDEFG'[:3]'ABC'在很多编程语言中,都为字符串提供了多种多样的截取函数(例如,substring),其实目的就是对字符串进行切片。Python没有字符串拦截功能。只需要切片即可完成,非常简单。S="abcdefg"print(S[:2])#abprint(S[::2])#acegprint(S[::3])#adg2.迭代如果给出一个列表或元组,我们可以通过循环遍历这个列表或元组,这种遍历我们称之为迭代(Iteration)。在Python中,迭代是通过for...in完成的,而在很多语言如C或Java中,迭代列表是通过下标完成的,Python的for循环抽象度高于Java的for循环,因为Python的for循环可以是不仅用于列表或元组,还用于其他可迭代对象。虽然list这个数据类型有下标,但是很多其他数据类型是没有下标的。但是只要是可迭代对象,不管有没有下标都可以迭代。例如,dict可以迭代:>>>d={'a':1,'b':2,'c':3}>>>forkeyind:...print(key)acb因为dict的存储不是按照list的顺序排列的,迭代出来的结果顺序很可能不一样。默认情况下,dict遍历键。如果要迭代value,可以在d.values()中使用forvalue,如果要同时迭代key和value,可以在d.items()中使用fork,v。由于字符串也是可迭代对象,因此也可以应用于for循环:>>>forchin'ABC':...print(ch)...ABC所以,当我们使用for循环时,我们只需要行动on一个可迭代对象,for循环是可以正常运行的,我们不太关心这个对象是列表还是其他数据类型。那么,如何判断一个对象是可迭代对象呢?方法是判断collections模块的Iterable类型:>>>fromcollectionsimportIterable>>>isinstance('abc',Iterable)#str是否为iterableTrue>>>isinstance([1,2,3],Iterable)#列表是否可迭代True>>>isinstance(123,Iterable)#整数是否可迭代False如果想为列表实现类似Java的下标循环怎么办?Python内置的enumerate函数可以把一个列表变成索引-元素对,这样索引和元素本身就可以在for循环中同时迭代:>>>fori,valueinenumerate(['A','B','C']):...在print(i,value)上面的for循环中,同时引用了两个变量,这在Python中很常见,比如下面的代码:>>>forx,yin[(1,1),(2,4),(3,9)]:...print(x,y)任何可迭代对象都可以作用于for循环,包括我们的自定义数据类型,只要满足迭代条件,就可以使用for循环。3.列表生成是ListComprehensions,这是一个非常简单但功能强大的Python内置生成器,可以用来创建列表。例如,要生成列表[1,2,3,4,5,6,7,8,9,10],您可以使用list(range(1,11))生成[1x1,2x2,3x3,...,10x10]怎么做呢?第一种方法是循环:>>>L=[]>>>forxinrange(1,11):...L.append(x*x)...>>>L[1,4,9,16,25,36,49,64,81,100]列表生成公式可以用一行语句代替循环生成上面的列表([1x1,2x2,3x3,...,10x10]):[x*xforxinrange(1,11)]写列表生成公式时,把要生成的元素x*x放在前面,后面是for循环,就可以创建列表,进行if判断即可在for循环之后添加,这样我们就可以只过滤掉偶数方块:>>>[x*xforxinrange(1,11)ifx%2==0][4,16,36,64,100]也可以使用两层循环,可以生成全排列:>>>[m+nformin'ABC'fornin'XYZ']['AX','AY','AZ','BX','BY','BZ','CX','CY','CZ']使用列表生成很少使用三层或更多层的循环,可以编写非常简洁的代码。比如列出当前目录下的所有文件和目录名,一行代码就可以实现>>>importos#导入os模块,模块的概念后面会讲到>>>[dfordinos.listdir('.')]#os.listdir可以列出文件和目录['.emacs.d','.ssh','.Trash','Adlm','Applications','Desktop','Documents','Downloads','Library','Movies','Music','Pictures','Public','VirtualBoxVMs','Workspace','XCode']for循环实际上可以使用两个或更多同时变量,比如dictitems()可以同时迭代key和value:>>>d={'x':'A','y':'B','z':'C'}>>>fork,vind.items():...print(k,'=',v)...y=Bx=Az=C因此,列表生成也可以使用两个变量来生成一个列表:>>>??d={'x':'A','y':'B','z':'C'}>>>[k+'='+vfork,vind.items()]['y=B','x=A','z=C']最后将列表中的所有字符串转换为小写:>>>L=['Hello','World','IBM','Apple']>>>[s.lower()forsinL]Exercise2L1=['Hello','World',18,'Apple',None]print([x.lower()ifisinstance(x,str)elsexforxinL1])4.Generator有了列表理解,我们可以直接创建一个列表。但是,由于内存限制,列表容量肯定是有限的。而且,创建一个包含100万个元素的列表,不仅占用大量存储空间,而且如果我们只需要访问前几个元素,后面的大部分元素占用的空间都会被浪费掉。那么,如果列表元素可以按照一定的算法计算出来,我们是不是可以在循环中不断计算后面的元素呢?由于不必创建完整列表,因此可以节省大量空间。在Python中,这种while循环计算的机制被称为生成器:generator。创建生成器的方法有很多种。第一种方法很简单,只要把alistgeneration的[]改成(),就创建了一个generator:g=(x*xforxinrange(10))
