八、切片
8-1 对list进行切片
>>> L[0:3]L[0:3]表示,从索引0开始取,直到索引3为止,但不包括索引3。即索引0,1,2,正好是3个元素。
['Adam', 'Lisa', 'Bart']
>>> L[:3]
['Adam', 'Lisa', 'Bart']
>>> L[1:3]
['Lisa', 'Bart']
>>> L[:]
['Adam', 'Lisa', 'Bart', 'Paul']
>>> L[::2]第三个参数表示每N个取一个,上面的 L[::2] 会每两个元素取出一个来,也就是隔一个取一个。
['Adam', 'Bart']
8-2 倒序切片
>>> L = ['Adam', 'Lisa', 'Bart', 'Paul']
>>> L[-2:]
['Bart', 'Paul']
>>> L[:-2]
['Adam', 'Lisa']
>>> L[-3:-1]
['Lisa', 'Bart']
>>> L[-4:-1:2]
['Adam', 'Bart']
8-3 对字符串切片
>>> 'ABCDEFG'[:3]
'ABC'
>>> 'ABCDEFG'[-3:]
'EFG'
>>> 'ABCDEFG'[::2]
'ACEG'
九、迭代
9-1 什么是迭代
注意: 集合是指包含一组元素的数据结构,我们已经介绍的包括:迭代与按下标访问数组最大的不同是,后者是一种具体的迭代实现方式,而前者只关心迭代结果,根本不关心迭代内部是如何实现的。
1. 有序集合:list,tuple,str和unicode;
2. 无序集合:set
3. 无序集合并且具有 key-value 对:dict
9-2 索引迭代
方法是使用 enumerate() 函数:
>>> L = ['Adam', 'Lisa', 'Bart', 'Paul']实际上,enumerate() 函数把:
>>> for index, name in enumerate(L):
... print index, '-', name
...
0 - Adam
1 - Lisa
2 - Bart
3 - Paul
['Adam', 'Lisa', 'Bart', 'Paul']变成了类似:
[(0, 'Adam'), (1, 'Lisa'), (2, 'Bart'), (3, 'Paul')]因此,迭代的每一个元素实际上是一个tuple。
9-3 迭代dict的value
我们已经了解了dict对象本身就是可迭代对象,用 for 循环直接迭代 dict,可以每次拿到dict的一个key。
如果我们希望迭代 dict 对象的value,应该怎么做?
dict 对象有一个 values() 方法,这个方法把dict转换成一个包含所有value的list,这样,我们迭代的就是 dict的每一个 value:
d = { 'Adam': 95, 'Lisa': 85, 'Bart': 59 }
print d.values()
# [85, 95, 59]
for v in d.values():
print v
# 85
# 95
# 59
如果仔细阅读Python的文档,还可以发现,dict除了values()方法外,还有一个 itervalues() 方法,用 itervalues() 方法替代 values() 方法,迭代效果完全一样:
d = { 'Adam': 95, 'Lisa': 85, 'Bart': 59 }
print d.itervalues()
# <dictionary-valueiterator object at 0x106adbb50>
for v in d.itervalues():
print v
# 85
# 95
# 59
那这两个方法有何不同之处呢?
1. values() 方法实际上把一个 dict 转换成了包含 value 的list。
2. 但是 itervalues() 方法不会转换,它会在迭代过程中依次从 dict 中取出 value,所以 itervalues() 方法比 values() 方法节省了生成 list 所需的内存。
3. 打印 itervalues() 发现它返回一个 <dictionary-valueiterator> 对象,这说明在Python中,for 循环可作用的迭代对象远不止 list,tuple,str,unicode,dict等,任何可迭代对象都可以作用于for循环,而内部如何迭代我们通常并不用关心。
如果一个对象说自己可迭代,那我们就直接用 for 循环去迭代它,可见,迭代是一种抽象的数据操作,它不对迭代对象内部的数据有任何要求。
9-4 迭代dict的key和value
>>> d = { 'Adam': 95, 'Lisa': 85, 'Bart': 59 }可以看到,items() 方法把dict对象转换成了包含tuple的list,我们对这个list进行迭代,可以同时获得key和value:
>>> print d.items()
[('Lisa', 85), ('Adam', 95), ('Bart', 59)]
>>> for key, value in d.items():和 values() 有一个 itervalues() 类似, items() 也有一个对应的 iteritems(),iteritems() 不把dict转换成list,而是在迭代过程中不断给出 tuple,所以, iteritems() 不占用额外的内存。
... print key, ':', value
...
Lisa : 85
Adam : 95
Bart : 59
十、列表生成式
10-1 生成列表
>>> range(1, 11)
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> [x * x for x in range(1, 11)]这种写法就是Python特有的列表生成式。利用列表生成式,可以以非常简洁的代码生成 list。
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
10-2 复杂表达式
使用for循环的迭代不仅可以迭代普通的list,还可以迭代dict。
假设有如下的dict:
d = { 'Adam': 95, 'Lisa': 85, 'Bart': 59 }
完全可以通过一个复杂的列表生成式把它变成一个 HTML 表格:
tds = ['<tr><td>%s</td><td>%s</td></tr>' % (name, score) for name, score in d.iteritems()]
print '<table>'
print '<tr><th>Name</th><th>Score</th><tr>'
print '\n'.join(tds)
print '</table>'
注:字符串可以通过 % 进行格式化,用指定的参数替代 %s。字符串的join()方法可以把一个 list 拼接成一个字符串。
10-3 条件过滤
>>> [x * x for x in range(1, 11) if x % 2 == 0]有了 if 条件,只有 if 判断为 True 的时候,才把循环的当前元素添加到列表中。
[4, 16, 36, 64, 100]
10-4 多层表达式
>>> [m + n for m in 'ABC' for n in '123']
['A1', 'A2', 'A3', 'B1', 'B2', 'B3', 'C1', 'C2', 'C3']
对有编程经验的人来说,快速过一遍该课程,有动手实践,能够快速过一遍Python的语法,印象深刻些,不像看书会枯燥和内容多。
课程逻辑清晰,比如怎样遍历、访问、更新dict和set,这样,当不记得时,有了个印象就可以快速回头翻这里。
总体来说,能够帮助有编程经验的人快速上手。