# 变量的指向问题a = "abc"b = aa = "def"print(a)print(b)
defabc
print(10/3) # 得出来的是小数print(10//3) # 得出来的是整数print(10%3) # 求余
3.333333333333333531
# 小结#Python支持多种数据类型,在计算机内部,可以把任何数据都看成一个“对象”,而变量就是在程序中用来指向这些数据对象的,#对变量赋值就是把数据和变量给关联起来。#对变量赋值x = y是把变量x指向真正的对象,该对象是变量y所指向的。随后对变量y的赋值不影响变量x的指向。#注意:Python的整数没有大小限制,而某些语言的整数根据其存储长度是有大小限制的,例如Java对32位整数的范围限制在-2147483648-2147483647。#Python的浮点数也没有大小限制,但是超出一定范围就直接表示为inf(无限大)。
# 字符串print('Hello, %s,您本月工资是 %s'%('hufei', 234112)) # 第一种'Hello, {0}, 您本月话费是 {1}'.format('hufei', 23.1) # 第二种# 编码# ASCII编码:最早只有127个字符被编码到计算机里,也就是大小写英文字母、数字和一些符号,这个编码表被称为ASCII编码.比如大写字母A的编码是65,小写字母z的编码是122。# Unicode把所有语言都统一到一套编码里,用二进制表示的。字母A用ASCII编码是十进制的65,二进制的01000001;字符0用ASCII编码是十进制的48,二进制的00110000# UTF-8编码:UTF-8编码把一个Unicode字符根据不同的数字大小编码成1-6个字节,常用的英文字母被编码成1个字节,汉字通常是3个字节,只有很生僻的字符才会被编码成4-6个字节。如果你要传输的文本包含大量英文字符,用UTF-8编码就能节省空间#ASCII编码是1个字节,而Unicode编码通常是2个字节,UTF-8不同语言大小不一样。# 计算机中的存储#计算机系统通用的字符编码工作方式:# 在计算机内存中,统一使用Unicode编码,当需要保存到硬盘或者需要传输的时候,就转换为UTF-8编码。# 用记事本编辑的时候,从文件读取的UTF-8字符被转换为Unicode字符到内存里,编辑完成后,保存的时候再把Unicode转换为UTF-8保存到文件
Hello, hufei,您本月工资是 234112'Hello, hufei, 您本月话费是 23.1'
# listname_list = ['研发总监', '服务端工程师', '前端工程师', '测试工程师']name_list.append('UI设计')name_list.insert(0, '老板')name_list
['老板', '研发总监', '服务端工程师', '前端工程师', '测试工程师', 'UI设计']
# tupleclassmates = ('Michael', 'Bob', 'Tracy')# tuple所谓的“不变”是说,tuple的每个元素,指向永远不变。即指向'a',就不能改成指向'b',指向一个list,就不能改成指向其他对象,但指向的这个list本身是可变的!
# dictd = {'Michael': 95, 'Bob': 75, 'Tracy': 85}# d.get('Bob')# d['Bob']# 请务必注意,dict内部存放的顺序和key放入的顺序是没有关系的。# 和list比较,dict有以下几个特点:# 查找和插入的速度极快,不会随着key的增加而变慢;# 需要占用大量的内存,内存浪费多。# 而list相反:# 查找和插入的时间随着元素的增加而增加;# 占用空间小,浪费内存很少。# 所以,dict是用空间来换取时间的一种方法。# dict可以用在需要高速查找的很多地方,在Python代码中几乎无处不在,正确使用dict非常重要,需要牢记的第一条就是dict的key必须是不可变对象。# 这是因为dict根据key来计算value的存储位置,如果每次计算相同的key得出的结果不同,那dict内部就完全混乱了。这个通过key计算位置的算法称为哈希算法(Hash)。# 要保证hash的正确性,作为key的对象就不能变。在Python中,字符串、整数等都是不可变的,因此,可以放心地作为key。而list是可变的,就不能作为key:
75
# set# set可以看成数学意义上的无序和无重复元素的集合,因此,两个set可以做数学意义上的交集、并集等操作s1 = set([1, 1, 2, 2, 3, 3])s2 = set([2, 3, 4, 3, 2])print(s1)print(s2)print(s1 & s2)print(s1 | s2)
{1, 2, 3}{2, 3, 4}{2, 3}{1, 2, 3, 4}
# 函数的参数def person(name, age, *, city='Beijing', job): print(name, age, city, job)person('Jack', 24, job='Engineer')# Python的函数具有非常灵活的参数形态,既可以实现简单的调用,又可以传入非常复杂的参数。# 默认参数一定要用不可变对象,如果是可变对象,程序运行时会有逻辑错误!# 要注意定义可变参数和关键字参数的语法:# *args是可变参数,args接收的是一个tuple;# **kw是关键字参数,kw接收的是一个dict。# 以及调用函数时如何传入可变参数和关键字参数的语法:# 可变参数既可以直接传入:func(1, 2, 3),又可以先组装list或tuple,再通过*args传入:func(*(1, 2, 3));# 关键字参数既可以直接传入:func(a=1, b=2),又可以先组装dict,再通过**kw传入:func(**{'a': 1, 'b': 2})。# 使用*args和**kw是Python的习惯写法,当然也可以用其他参数名,但最好使用习惯用法。# 命名的关键字参数是为了限制调用者可以传入的参数名,同时可以提供默认值。# 定义命名的关键字参数在没有可变参数的情况下不要忘了写分隔符*,否则定义的将是位置参数。
Jack 24 Beijing Engineer
# 递归及其优化# 归函数的优点是定义简单,逻辑清晰。理论上,所有的递归函数都可以写成循环的方式,但循环的逻辑不如递归清晰。# 使用递归函数需要注意防止栈溢出。在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,# 每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出。# 解决递归调用栈溢出的方法是通过尾递归优化,事实上尾递归和循环的效果是一样的,所以,把循环看成是一种特殊的尾递归函数也是可以的。# 尾递归是指,在函数返回的时候,调用自身本身,并且,return语句不能包含表达式。这样,编译器或者解释器就可以把尾递归做优化,# 使递归本身无论调用多少次,都只占用一个栈帧,不会出现栈溢出的情况。# 尾递归调用时,如果做了优化,栈不会增长,因此,无论多少次调用也不会导致栈溢出。# 遗憾的是,大多数编程语言没有针对尾递归做优化,Java,Python解释器也没有做优化,所以,即使把上面的fact(n)函数改成尾递归方式,也会导致栈溢出。# 应用:阶乘、斐波那契数列、汉诺塔