切片
切片操作是用来取list的前N个元素,当然我们可以用循环来实现这个操作
def qu(l,num):
x=0
L2=[]
while x<num:
L2.insert(x,L[x])
x=x+1
return L2
L3=qu(['a','b','c','d'], 2)
#取出前两个数
print(L3)
或者
r = []
n = 3
for i in range(n):
r.append(L[i])
切片(Slice)操作符,能大大简化这种操作
L[0:3]
['Adam', 'Lisa', 'Bart']
#如果是从0开始取,0可以省略 也就是L[:3],L[:]表示从头到尾
L[::2]
['Adam', 'Bart']
第三个参数表示每N个取一个,上面的 L[::2] 会每两个元素取出一个来,也就是隔一个取一个。
把list换成tuple,切片操作完全相同,只是切片的结果也变成了tuple。
任务
range()函数可以创建一个数列:
>>> range(1, 101)
[1, 2, 3, ..., 100]
请利用切片,取出:
- 前10个数;
- 3的倍数;
- 不大于50的5的倍数。
L = range(1, 101)
print( L[1:11])
print( L[2:3])
print( L[4:50:5])
输出:
range(1, 11)
range(3, 4)
range(5, 51, 5)
#不知道是什么鬼····
查了一下,python3取消了range,同时将xrange重新命名成range,如果希望像py2一样可以打印出来整个结构需要list(range(…))
L = range(1, 101)
print( list(L[:10]))
print( list(L[2::3]))
print( list(L[4:50:5]))
输出:
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
[3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39, 42, 45, 48, 51, 54, 57, 60, 63, 66, 69, 72, 75, 78, 81, 84, 87, 90, 93, 96, 99]
[5, 10, 15, 20, 25, 30, 35, 40, 45, 50]
倒序切片
>>> L = ['Adam', 'Lisa', 'Bart', 'Paul']
>>> L[-2:]
['Bart', 'Paul']
>>> L[:-2]
['Adam', 'Lisa']
>>> L[-3:-1]
['Lisa', 'Bart']
>>> L[-4:-1:2]
['Adam', 'Bart']
倒序切片包含起始索引,不包含结束索引。
任务
利用倒序切片对 1 - 100 的数列取出:
- 最后10个数;
- 最后10个5的倍数。
L = range(1, 101)
print L[-10:]
print L[-46::5]
字符串切片
>>> 'ABCDEFG'[:3]
'ABC'
>>> 'ABCDEFG'[-3:]
'EFG'
>>> 'ABCDEFG'[::2]
'ACEG'
任务
字符串有个方法 upper() 可以把字符变成大写字母:
'abc'.upper()
>>>'ABC'
但它会把所有字母都变成大写。请设计一个函数,它接受一个字符串,然后返回一个仅首字母变成大写的字符串。
取除首字母外的字符串用[1:]
参考代码:
def firstCharUpper(s):
return s[0].upper() + s[1:]
print firstCharUpper('hello')
print firstCharUpper('sunday')
print firstCharUpper('september')
列表生成式
要生成[1x1, 2x2, 3x3, …, 10x10]怎么做?
方法一是循环:
L=[]
for x in range(1,11):
L.append(x*x)
print(L)
方法二、使用列表生成式
print([x * x for x in range(1, 11)])
任务
请利用列表生成式生成列表 [1x2, 3x4, 5x6, 7x8, …, 99x100]
提示:range(1, 100, 2) 可以生成list [1, 3, 5, 7, 9,…]
[x * (x+1) for x in range(1, 100, 2)]
条件过滤
[x * x for x in range(1, 11)]
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
如果我们只想要偶数的平方,不改动 range()的情况下,可以加上 if 来筛选:
>>> [x * x for x in range(1, 11) if x % 2 == 0]
[4, 16, 36, 64, 100]
有了 if 条件,只有 if 判断为 True 的时候,才把循环的当前元素添加到列表中。
任务:
请编写一个函数,它接受一个 list,然后把list中的所有字符串变成大写后返回,非字符串元素将被忽略。
提示:
- isinstance(x, str) 可以判断变量 x 是否是字符串;
- 字符串的 upper() 方法可以返回大写的字母。
def toUppers(L):
return [x.upper() for x in L if isinstance(x, str)]
print( toUppers(['Hello', 'world', 101]))
多层表达式
任务:
利用 3 层for循环的列表生成式,找出对称的 3 位数。例如,121 就是对称数,因为从右到左倒过来还是 121。
L=[]
for i in range(1,10):
for j in range(0,10):
for k in range(1,10):
if i==k:
L.append(i*100+j*10+k)
print(L)
索引迭代
对于有序集合,元素确实是有索引的。有的时候,我们确实想在 for 循环中拿到索引,怎么办?方法是使用 enumerate() 函数:
>>> L = ['Adam', 'Lisa', 'Bart', 'Paul']
>>> for index, name in enumerate(L):
... print index, '-', name
...
0 - Adam
1 - Lisa
2 - Bart
3 - Paul
使用 enumerate() 函数,我们可以在for循环中同时绑定索引index和元素name。但是,这不是 enumerate() 的特殊语法。实际上,enumerate() 函数把:
['Adam', 'Lisa', 'Bart', 'Paul']
# 变成了类似:
[(0, 'Adam'), (1, 'Lisa'), (2, 'Bart'), (3, 'Paul')]
因此,迭代的每一个元素实际上是一个tuple:
for t in enumerate(L):
index = t[0]
name = t[1]
print index, '-', name
如果我们知道每个tuple元素都包含两个元素,for循环又可以进一步简写为:
for index, name in enumerate(L):
print index, '-', name
这样不但代码更简单,而且还少了两条赋值语句。
可见,索引迭代也不是真的按索引访问,而是由 enumerate() 函数自动把每个元素变成 (index, element) 这样的tuple,再迭代,就同时获得了索引和元素本身。
任务
zip()函数可以把两个 list 变成一个 list:
>>> zip([10, 20, 30], ['A', 'B', 'C'])
[(10, 'A'), (20, 'B'), (30, 'C')]
在迭代 [‘Adam’, ‘Lisa’, ‘Bart’, ‘Paul’] 时,如果我们想打印出名次 - 名字(名次从1开始),请考虑如何在迭代中打印出来。
提示:考虑使用zip()函数和range()函数
L = ['Adam', 'Lisa', 'Bart', 'Paul']
for index, name in zip(range(1, len(L)+1), L):
print(index, '-', name)
迭代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
迭代dict的key和value
d = { 'Adam': 95, 'Lisa': 85, 'Bart': 59 }
print( d.items())
output:
dict_items([('Adam', 95), ('Lisa', 85), ('Bart', 59)])