切片
取一个list或tuple的部分元素,可以这样操作:
# 从索引0开始取,到3为止,不包括3.
list[0:3]
tuple[0:3]
练习
利用切片操作,实现一个trim()函数,去除字符串首尾的空格
def trim(s):
if len(s) == 0:
return s
while len(s) != 0 and s[0] == ' ':
s = s[1:]
while len(s) != 0 and s[-1] == ' ':
s = s[:-1]
return s
总结:这其实是一个比较笨的方法,绕过了数组下标越界的判断。当遇到空字符串和空格字符串时,尤其是空字符串,如果判断s[0]==0.
这时程序会报错。
这里选择的解决方法是,每次都先进行长度的判断。
还有另外一种方法更好:
def trim(s):
while s[:1] == ' ':
s = s[1:]
while s[-1:] == ' ':
s = s[:-1]
return s
在判断循环条件时直接只对第一个或最后一个字符判断,在进行这样的判断时,python编译器在遇到切片越界时不会报错。
迭代
如果给定一个list
或tuple
,我们可以通过for
循环来遍历这个list
或tuple
,这种遍历我们称为迭代(Iteration)。
在迭代dict时,默认迭代key,也可以用 d.values()选择迭代value,可以选择d.items()迭代 键和值。
for k in d()
for v in d.values()
for k,v in d.items()
字符串也是可迭代对象,
for ch in 'ABC'
>>> A
>>> B
>>> C
判断一个对象是否为迭代对象。
方法是通过collections.abc模块的Iterable类型判断:
from collections.abc import Iterable
print(isinstance('123', Iterable)) >>> TRUE
print(isinstance([1,2,3], Iterable)) >>> TRUE
print(isinstance(123, Iterable)) >>> FALSE
如果要对list
实现类似Java那样的下标循环怎么办?Python内置的enumerate
函数可以把一个list
变成索引-元素对,这样就可以在for
循环中同时迭代索引和元素本身:
l = ['a', 'b', 'c']
for i,value in enumerate(l):
print(i,value)
# 生成的i值索引从0开始
列表生成式
列表生成式即List Comprehensions,是Python内置的非常简单却强大的可以用来创建list的生成式。
要生成list[1,2,3,4,5,6,7,8,9,10]时,可以用
list(range(1,11))
如果要生成[1x1, 2x2, 3x3, ..., 10x10]
怎么做?方法一是循环:
l = []
for x in range(1, 11):
l.append(x * x)
方法2:
[x*x for x in range(1,11)]
写列表生成式时,把要生成的元素x * x
放到前面,后面跟for
循环,就可以把list创建出来,十分有用,多写几次,很快就可以熟悉这种语法。
for循环后面还可以加上if判断,这样我们就可以筛选出仅偶数的平方:
print([x*x for x in range(1,11) if x % 2 == 0])
>>> [4, 16, 36, 64, 100]
还可以使用两层循环,可以生成全排列:
print([m+n for m in 'XYZ' for n in 'ABC'])
>>> ['XA', 'XB', 'XC', 'YA', 'YB', 'YC', 'ZA', 'ZB', 'ZC']
运用列表生成式,可以写出非常简洁的代码。例如,列出当前目录下的所有文件和目录名,可以通过一行代码实现:
import os
print([d for d in os.listdir('.')])
>>> ['.idea', '01.hello.py', 'main.py', 'test.py', 'venv']
列表生成式也可以使用两个变量来生成list:
>>> d = {'x': 'A', 'y': 'B', 'z': 'C' }
>>> [k + '=' + v for k, v in d.items()]
['y=B', 'x=A', 'z=C']
最后把一个list中所有的字符串变成小写:
>>> L = ['Hello', 'World', 'IBM', 'Apple']
>>> [s.lower() for s in L]
['hello', 'world', 'ibm', 'apple']
在一个列表生成式中,for
前面的if ... else
是表达式,而for
后面的if
是过滤条件,不能带else
。
>>> [x if x % 2 == 0 else -x for x in range(1, 11)]
[-1, 2, -3, 4, -5, 6, -7, 8, -9, 10]
练习:字符串变小写,其余变量丢弃
L1=[...]
L2 = [x.lower() for x in L1 if isinstance(x, str)]
生成器
如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢?这样就不必创建完整的list,从而节省大量的空间。在Python中,这种一边循环一边计算的机制,称为生成器:generator。
要创建一个generator,有很多种方法。第一种方法很简单,只要把一个列表生成式的[]
改成()
,就创建了一个generator:
>>> L = [x * x for x in range(10)]
>>> L
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
>>> g = (x * x for x in range(10))
>>> g
<generator object <genexpr> at 0x1022ef630>
创建L
和g
的区别仅在于最外层的[]
和()
,L
是一个list,而g
是一个generator。