在Python交互模式下输入
exit()
并回车,就退出了Python交互模式,并回到命令行模式.1个中文字符经过UTF-8编码后通常会占用3个字节,而1个英文字符只占用1个字节。
如果要取最后一个元素,除了计算索引位置外,还可以用
-1
做索引,直接获取最后一个元素只有1个元素的tuple定义时必须加一个逗号
,
,来消除歧义:list和tuple是Python内置的有序集合,一个可变,一个不可变。
这是因为
input()
返回的数据类型是str
,str
不能直接和整数比较,必须先把str
转换成整数。Python提供了int()
函数来完成这件事情原来
int()
函数发现一个字符串并不是合法的数字时就会报错,程序就退出了。由于一个key只能对应一个value,所以,多次对一个key放入value,后面的值会把前面的值冲掉。
返回
None
的时候Python的交互环境不显示结果。和list比较,dict有以下几个特点:
- 查找和插入的速度极快,不会随着key的增加而变慢;
- 需要占用大量的内存,内存浪费多。
- 用空间换取时间的方法
而list相反:
- 查找和插入的时间随着元素的增加而增加;
- 占用空间小,浪费内存很少。
要保证hash的正确性,作为key的对象就不能变。在Python中,字符串、整数等都是不可变的,因此,可以放心地作为key。而list是可变的,就不能作为key
set的原理和dict一样,所以,同样不可以放入可变对象
也可以在交互式命令行通过
help(abs)
查看abs
函数的帮助信息在Python交互环境中定义函数时,注意Python会出现
...
的提示。函数定义结束后需要按两次回车重新回到>>>
提示符下:可以在该文件的当前目录下启动Python解释器,用
from abstest import
来导入
my_absmy_abs()
函数,注意abstest
是文件名(不含.py
扩展名)
练习:
请定义一个函数quadratic(a, b, c)
,接收3个参数,返回一元二次方程:
ax2 + bx + c = 0
的两个解。
提示:计算平方根可以调用math.sqrt()
函数:
import math
def quadratic(a,b,c):
t=pow(b,2)-4*a*c
if t>=0:
x1=(-b+math.sqrt(t))/(2*a)
x2=(-b-math.sqrt(t))/(2*a)
return (x1,x2)
elif t<0:
return
print('quadratic(2, 3, 1) =', quadratic(2, 3, 1))
一是必选参数在前,默认参数在后,否则Python的解释器会报错
当函数有多个参数时,把变化大的参数放前面,变化小的参数放后面。变化小的参数就可以作为默认参数。
定义默认参数要牢记一点:默认参数必须指向不变对象!
使用命名关键字参数时,要特别注意,如果没有可变参数,就必须加一个*
作为特殊分隔符。如果缺少*
参数定义的顺序必须是:必选参数、默认参数、可变参数、命名关键字参数和关键字参数。
练习:
以下函数允许计算两个数的乘积,请稍加改造,变成可接收一个或多个数并计算乘积:
# -*- coding: utf-8 -*-
----
def product(x, y):
return x * y
def product(*y):
mut=1
for n in y:
mut=mut*n
return mut
# 测试
print('product(5) =', product(5))
print('product(5, 6) =', product(5, 6))
print('product(5, 6, 7) =', product(5, 6, 7))
print('product(5, 6, 7, 9) =', product(5, 6, 7, 9))
if product(5) != 5:
print('测试失败!')
elif product(5, 6) != 30:
print('测试失败!')
elif product(5, 6, 7) != 210:
print('测试失败!')
elif product(5, 6, 7, 9) != 1890:
print('测试失败!')
else:
try:
product()
print('测试失败!')
except TypeError:
print('测试成功!')
使用递归函数需要注意防止栈溢出。在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出。
解决递归调用栈溢出的方法是通过尾递归优化,事实上尾递归和循环的效果是一样的,所以,把循环看成是一种特殊的尾递归函数也是可以的。
尾递归是指,在函数返回的时候,调用自身本身,并且,return语句不能包含表达式。这样,编译器或者解释器就可以把尾递归做优化,使递归本身无论调用多少次,都只占用一个栈帧,不会出现栈溢出的情况。
练习:
利用切片操作,实现一个trim()函数,去除字符串首尾的空格,注意不要调用str的strip()
方法:
# -*- coding: utf-8 -*-
def trim(s):
----
return s
----
- 利用递归实现,如果字符串为空,则返回该字符串,否则继续判断字符串首尾是否为空。
def trim(s):
if len(s)==0:
return s
elif s[0]==' ':
return (trim(s[1:]))
elif s[-1]==' ':
return (trim(s[:-1]))
return s
#测试
if trim('hello ') != 'hello':
print('测试失败!')
elif trim(' hello') != 'hello':
print('测试失败!')
elif trim(' hello ') != 'hello':
print('测试失败!')
elif trim(' hello world ') != 'hello world':
print('测试失败!')
elif trim('') != '':
print('测试失败!')
elif trim(' ') != '':
print('测试失败!')
else:
print('测试成功!')
迭代练习:
请使用迭代查找一个list中最小和最大值,并返回一个tuple:请使用迭代查找一个list中最小和最大值,并返回一个tuple:
def findMinAndMax(L):
if L==[]:
return (None,None)
else:
max=L[0]
min=L[0]
for x in L:
if max<x:
max=x
if min>x:
min=x
return (min,max)
# 测试
if findMinAndMax([]) != (None, None):
print('测试失败!')
elif findMinAndMax([7]) != (7, 7):
print('测试失败!')
elif findMinAndMax([7, 1]) != (1, 7):
print('测试失败!')
elif findMinAndMax([7, 1, 3, 9, 5]) != (1, 9):
print('测试失败!')
else:
print('测试成功!')
列表生成式练习:
请修改列表生成式,通过添加if
语句保证列表生成式能正确地执行:
L1=['Hello','World',18,'Apple',None]
L2=[s.lower() for s in L1 if isinstance(s,str)]
# 测试:
print(L2)
if L2 == ['hello', 'world', 'apple']:
print('测试通过!')
else:
print('测试失败!')
generator和函数的执行流程不一样。函数是顺序执行,遇到return
语句或者最后一行函数语句就返回。而变成generator的函数,在每次调用next()
的时候执行,遇到yield
语句返回,再次执行时从上次返回的yield
语句处继续执行。
杨辉三角:生成器练习:
def triangles():
L=[1]
while True:
yield L
L.append(0)
L=[L[i-1]+L[i] for i in range(len(L))]
# 期待输出:
# [1]
# [1, 1]
# [1, 2, 1]
# [1, 3, 3, 1]
# [1, 4, 6, 4, 1]
# [1, 5, 10, 10, 5, 1]
# [1, 6, 15, 20, 15, 6, 1]
# [1, 7, 21, 35, 35, 21, 7, 1]
# [1, 8, 28, 56, 70, 56, 28, 8, 1]
# [1, 9, 36, 84, 126, 126, 84, 36, 9, 1]
n = 0
results = []
for t in triangles():
print(t)
results.append(t)
n = n + 1
if n == 10:
break
if results == [
[1],
[1, 1],
[1, 2, 1],
[1, 3, 3, 1],
[1, 4, 6, 4, 1],
[1, 5, 10, 10, 5, 1],
[1, 6, 15, 20, 15, 6, 1],
[1, 7, 21, 35, 35, 21, 7, 1],
[1, 8, 28, 56, 70, 56, 28, 8, 1],
[1, 9, 36, 84, 126, 126, 84, 36, 9, 1]
]:
print('测试通过!')
else:
print('测试失败!')
一个函数就可以接收另一个函数作为参数,这种函数就称之为高阶函数
map/reduce练习:
利用map()
函数,把用户输入的不规范的英文名字,变为首字母大写,其他小写的规范名字。输入:['adam', 'LISA', 'barT']
,输出:['Adam', 'Lisa', 'Bart']
:
def normalize(name):
return name[0].upper()+name[1:].lower()
# 测试:
L1 = ['adam', 'LISA', 'barT']
L2 = list(map(normalize, L1))
print(L2)
练习2:
Python提供的sum()
函数可以接受一个list并求和,请编写一个prod()
函数,可以接受一个list并利用reduce()
求积:
from functools import reduce
def prod(L):
return reduce(lambda x,y:x*y,L)
print('3 * 5 * 7 * 9 =', prod([3, 5, 7, 9]))
if prod([3, 5, 7, 9]) == 945:
print('测试成功!')
else:
print('测试失败!')
sorted()练习:
假设我们用一组tuple表示学生名字和成绩:
L = [('Bob', 75), ('Adam', 92), ('Bart', 66), ('Lisa', 88)]
请用sorted()
对上述列表分别按名字和成绩排序:
L = [('Bob', 75), ('Adam', 92), ('Bart', 66), ('Lisa', 88)]
def by_name(t):
return t[0].lower()
L2=sorted(L,key=by_name)
print(L2)
def by_score(t):
return t[1]
L2 = sorted(L, key=by_score)
print(L2)
回数:筛选的练习
def is_palindrome(n):
nn=str(n)
return nn==nn[::-1]#反转字符串
# 测试:
output = filter(is_palindrome, range(1, 1000))
print('1~1000:', list(output))
if list(filter(is_palindrome, range(1, 200))) == [1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 22, 33, 44, 55, 66, 77, 88, 99,
101, 111, 121, 131, 141, 151, 161, 171, 181, 191]:
print('测试成功!')
else:
print('测试失败!')