python小练习-列表、字典
1、 切片(Slice)
L=['a','b','c','d']
L[0:2]表示从索引0
开始取,直到索引2
为止,但不包括索引2
。即索引0
,1,
正好是2个元素
如果第一个索引是0
,还可以省略:
L[:2]
L[-1]
取倒数第一个元素
L[:]表示从第一个到最后一个,即原样复制一个list
L[::2]去全部数据,但是每两个取一个
字符串逆序:
str = “abcdefg”
str1 = str[::-1] # “gfedcba”
#1、去字符串两边的空格
1 #1、去字符串2边的空格 2 def trim(s): 3 if s=="": 4 return s 5 while(s[0]==" "): 6 s = s[1:] 7 if s == "": 8 return s 9 while(s[-1]==" "): 10 s = s[:-1] 11 if s == "": 12 return s 13 return s 14 15 16 if __name__ == '__main__': 17 # 1、测试: 18 if trim('hello ') != 'hello': 19 print('测试失败!') 20 elif trim(' hello') != 'hello': 21 print('测试失败!') 22 elif trim(' hello ') != 'hello': 23 print('测试失败!') 24 elif trim(' hello world ') != 'hello world': 25 print('测试失败!') 26 elif trim('') != '': 27 print('测试失败!') 28 elif trim(' ') != '': 29 print('测试失败!') 30 else: 31 print('测试成功!')
2、迭代
如果给定一个list或tuple,我们可以通过for
循环来遍历这个list或tuple,这种遍历我们称为迭代(Iteration),迭代是通过for ... in
来完成的
d = {'a':1,'b':2,'c':3,'d':4}
for key in d:
print(key)
for value in d.values():
print(value )
for k ,v in d.items():
print(k,v)
Python内置的enumerate
函数可以把一个list变成索引-元素对,这样就可以在for
循环中同时迭代索引和元素本身:
for i ,value in enumerate(['a','b','c','d']):
print(i,value)
#2、请使用迭代查找一个list中最小和最大值,并返回一个tuple:
1 def findMinAndMax(L): 2 if len(L) == 0: 3 return (None, None) 4 5 max = L[0] 6 min = L[0] 7 for num in L: 8 if num > max: 9 max = num 10 if num < min: 11 min = num 12 return(min,max) 13 14 # 测试 15 if findMinAndMax([]) != (None, None): 16 print('测试失败!') 17 elif findMinAndMax([7]) != (7, 7): 18 print('测试失败!') 19 elif findMinAndMax([7, 1]) != (1, 7): 20 print('测试失败!') 21 elif findMinAndMax([7, 1, 3, 9, 5]) != (1, 9): 22 print('测试失败!') 23 else: 24 print('测试成功!')
3、列表生成式
列表生成式即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)
方法二:列表生成式
L = [x * x for x in range(1,11)]
写列表生成式时,把要生成的元素x * x
放到前面,后面跟for
循环,就可以把list创建出来
for循环后面还可以加上if判断
L = [x * x for x in range(1,11) if x % 2 == 0]
还可以使用两层循环,可以生成全排列:
[a * b for a in [1,2,3] for b in [4,5,6]]
最后把一个list中所有的字符串变成小写:
L=["alice","JACk","Steven","Catherine"]
[s.lower() for s in L]
# list中既包含字符串,又包含整数
1 def listgenerate(): 2 L1 = ['Hello', 'World', 18, 'Apple', None] 3 L2 = [s.lower() for s in L1 if isinstance(s, str)] 4 5 # 测试: 6 print(L2) 7 if L2 == ['hello', 'world', 'apple']: 8 print('测试通过!') 9 else: 10 print('测试失败!')
4、生成器
通过列表生成式,我们可以直接创建一个列表。但是,受到内存限制,列表容量肯定是有限的。而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费了。
所以,如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢?这样就不必创建完整的list,从而节省大量的空间。在Python中,这种一边循环一边计算的机制,称为生成器:generator。
要创建一个generator,有很多种方法。第一种方法很简单,只要把一个列表生成式的[]
改成()
,就创建了一个generator:
L = [x * x for x in range(10)]
g = (x * x for x in range(10))
创建L
和g
的区别仅在于最外层的[]
和()
,L
是一个list,而g
是一个generator。
通过next()
函数获得generator的下一个返回值:next(g)
generator非常强大。如果推算的算法比较复杂,用类似列表生成式的for
循环无法实现的时候,还可以用函数来实现
比如,著名的斐波拉契数列(Fibonacci),除第一个和第二个数外,任意一个数都可由前两个数相加得到:
1 def fib(max): 2 n, a, b = 0, 0, 1 3 while n < max: 4 print(b)#将print(b)
改为yield b,就可以变成生成器
5 a, b = b, a + b 6 n = n + 1 7 return 'done'
这就是定义generator的另一种方法。如果一个函数定义中包含yield
关键字,那么这个函数就不再是一个普通函数,而是一个generator:
这里,最难理解的就是generator和函数的执行流程不一样。函数是顺序执行,遇到return
语句或者最后一行函数语句就返回。而变成generator的函数,在每次调用next()
的时候执行,遇到yield
语句返回,再次执行时从上次返回的yield
语句处继续执行。
#输出杨辉三角
1 ''' 2 杨辉三角定义如下: 3 1 4 / \ 5 1 1 6 / \ / \ 7 1 2 1 8 / \ / \ / \ 9 1 3 3 1 10 / \ / \ / \ / \ 11 1 4 6 4 1 12 / \ / \ / \ / \ / \ 13 1 5 10 10 5 1 14 把每一行看做一个list,试写一个generator,不断输出下一行的list: 15 ''' 16 def triangles(): 17 L = [1] 18 n = 1 19 while True: 20 print(L) 21 if n>5: 22 break 23 S = L[:] 24 S.append(0)#重点在于此,实现错位相加 25 L = [S[i-1] + S[i] for i in range(len(S))] 26 n += 1
5、map()
函数接收两个参数,一个是函数,一个是Iterable
,map
将传入的函数依次作用到序列的每个元素,并把结果作为新的Iterator
返回。
1 def func(x): 2 return x * x 3 4 i = map(func, [1, 2, 3, 4, 5, 6, 7, 8, 9]) 5 6 print(list(i))
Iterator
是惰性序列,因此通过list()
函数让它把整个序列都计算出来并返回一个list
6、reduce
把一个函数作用在一个序列[x1, x2, x3, ...]
上,这个函数必须接收两个参数,reduce
把结果继续和序列的下一个元素做累积计算,其效果就是:
reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)
1 #比方说对一个序列求和,就可以用reduce实现 2 from functools import reduce 3 def add(x, y): 4 return x+y 5 6 reduce(add,[1,2,3,4,5,6,7,8,9])
1 #序列[1, 2, 3, 4, 5]变换成整数12345 2 from functools import reduce 3 def fn(x, y): 4 return x * 10 + y 5 6 reduce(fn,[1,2,3,4,5])
1 #将字符串转换为整数 2 from functools import reduce 3 4 dic = {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9} 5 6 def char2num(ch): 7 return dic [ch] 8 9 def str2int(s): 10 return reduce(lambda x, y: x * 10 + y, map(char2num, s))
1 #1、利用map()函数,把用户输入的不规范的英文名字,变为首字母大写,其他小写的规范名字 2 def normalize(name): 3 s = "" 4 for k,v in enumerate(name): 5 if k ==0 : 6 s += (v.upper()) 7 else: 8 s += (v.lower()) 9 return s 10 11 # 测试: 12 L1 = ['adam', 'LISA', 'barT'] 13 L2 = list(map(normalize, L1)) 14 print(L2) 15 16 ''' 17 2、Python提供的sum()函数可以接受一个list并求和, 18 请编写一个prod()函数,可以接受一个list并利用reduce()求积: 19 ''' 20 from functools import reduce 21 def prod(L): 22 23 def mul(a,b): 24 return(a*b) 25 26 return reduce(mul,L) 27 28 print('3 * 5 * 7 * 9 =', prod([3, 5, 7, 9])) 29 if prod([3, 5, 7, 9]) == 945: 30 print('测试成功!') 31 else: 32 print('测试失败!') 33 34 ''' 35 3、利用map和reduce编写一个str2float函数, 36 把字符串'123.456'转换成浮点数123.456: 37 ''' 38 DIGITS = {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9} 39 def str2float(s): 40 a, b = s.split('.') #把字符串拆分成a,b两部分 41 return str2int(a) + str2int(b)/10**len(b) 42 43 def str2int(s): 44 digits = {'0':0, '1':1, '2':2, '3':3, '4':4, '5':5, '6':6, '7':7, '8':8, '9':9} 45 digit_array = map(lambda x: digits[x], s) 46 return reduce(lambda x, y: x*10 + y, digit_array) 47 48 49 def char2num(s): 50 51 return map(DIGITS[s],s) 52 53 print('str2float(\'123.456\') =', str2float('123.456')) 54 if abs(str2float('123.456') - 123.456) < 0.00001: 55 print('测试成功!') 56 else: 57 print('测试失败!')