基础概念
-
tuple与list
- tuple是引用不可变的有序列表
- list是引用可变的有序列表
>>> t = ('a', 'b', ['A', 'B'])
>>> t[2][0] = 'X'
>>> t[2][1] = 'Y'
>>> t
('a', 'b', ['X', 'Y'])
表面上看,tuple的元素变了,但其实变的不是tuple的元素,而是list的元素。tuple一开始指向的list并没有改成别的list,所以,tuple所谓的“不变”是说,tuple的每个元素,引用永远不变。即指向'a',就不能改成指向'b',指向一个list,就不能改成指向其他对象,但指向的这个list本身是可变的!
-
if...else
if <条件判断1>:
<执行1>
elif <条件判断2>:
<执行2>
elif <条件判断3>:
<执行3>
else:
<执行4>
-
True_False
- 只要x是非零数值、非空字符串、非空list等,就判断为True,否则为False:非0为真
-
三种循环
- for...in...range(100)
sum = 0
for x in range(101):
sum = sum + x
print sum
+ while True:
```
sum = 0
n = 99
while n > 0:
sum = sum + n
n = n - 2
print sum
-
string_to_int
birth = int(raw_input('birth: '))
-
list_dict
- 异同点
dict特点:
查找和插入的速度极快,不会随着key的增加而增加;
需要占用大量的内存,内存浪费多。
而list相反:
查找和插入的时间随着元素的增加而增加;
占用空间小,浪费内存很少。
所以,dict是用空间来换取时间的一种方法。
dict可以用在需要高速查找的很多地方,在Python代码中几乎无处不在,正确使用dict非常重要,需要牢记的第一条就是dict的key必须是不可变对象。
这是因为dict根据key来计算value的存储位置,如果每次计算相同的key得出的结果不同,那dict内部就完全混乱了。这个通过key计算位置的算法称为哈希算法(Hash)。
要保证hash的正确性,作为key的对象就不能变。在Python中,字符串、整数等都是不可变的,因此,可以放心地作为key。而list是可变的,就不能作为key。
- 异同点
-
set
- 初始化set,通过list构造
>>> s = set([1, 2, 3])
>>> s
set([1, 2, 3])
-
set可以看成数学意义上的无序和无重复元素的集合,因此,两个set可以做数学意义上的交集、并集等操作:
s1 = set([1, 2, 3])
s2 = set([2, 3, 4])
s1 & s2
set([2, 3])
s1 | s2
set([1, 2, 3, 4])
8. ##### 函数
- 函数名其实就是指向一个**函数对象的引用**,完全可以把函数名赋给一个变量,相当于给这个函数起了一个“别名”:
```
>>> a = abs # 变量a指向abs函数
>>> a(-1) # 所以也可以通过a调用abs函数
1
- 返回多个值:返回的是一个tuple(,)
import math
def move(x, y, step, angle=0):
nx = x + step * math.cos(angle)
ny = y - step * math.sin(angle)
return nx, ny
>>> x, y = move(100, 100, 60, math.pi / 6)
>>> print x, y
151.961524227 70.0
- 默认参数必须指向不变对象
#一是必选参数在前,默认参数在后,否则Python的解释器会报错(思考一下为什么默认参数不能放在必选参数前面);
#
#二是如何设置默认参数。
def enroll(name, gender, age=6, city='Beijing'):
print 'name:', name
print 'gender:', gender
print 'age:', age
print 'city:', city
#--------------------------------------------------------------------------
>>> enroll('Bob', 'M', 7)
>>>enroll('Adam', 'M', city='Tianjin')
-
可变参数 ** *args*: 在list或tuple前面加一个号,把list或tuple的元素变成可变参数传进去:
nums = [1, 2, 3]
calc(*nums)
14
- 关键字参数** \*\*kw ** :0个或任意个含参数名的参数,这些关键字参数在函数内部自动组装为一个dict。
def person(name, age, **kw):
print 'name:', name, 'age:', age, 'other:', kw
-----------------------------------------------------------------------
person('Michael', 30)
name: Michael age: 30 other: {}
person('Adam', 45, gender='M', job='Engineer')
name: Adam age: 45 other: {'gender': 'M', 'job': 'Engineer'}
- **参数组合**:参数定义的顺序必须是:必选参数、默认参数、可变参数和关键字参数。
def func(a, b, c=0, *args, **kw):
print 'a =', a, 'b =', b, 'c =', c, 'args =', args, 'kw =', kw
-----------------------------------------------------------------------
func(1, 2, c=3)
a = 1 b = 2 c = 3 args = () kw = {}
func(1, 2, 3, 'a', 'b')
a = 1 b = 2 c = 3 args = ('a', 'b') kw = {}
func(1, 2, 3, 'a', 'b', x=99)
print x, y
151.961524227 70.0
- 默认参数**必须指向不变对象**
#一是必选参数在前,默认参数在后,否则Python的解释器会报错(思考一下为什么默认参数不能放在必选参数前面);
#
#二是如何设置默认参数。
def enroll(name, gender, age=6, city='Beijing'):
print 'name:', name
print 'gender:', gender
print 'age:', age
print 'city:', city
#--------------------------------------------------------------------------
>>> enroll('Bob', 'M', 7)
>>>enroll('Adam', 'M', city='Tianjin')
- 可变参数 ** \*args**: 在list或tuple前面加一个*号,把list或tuple的元素变成可变参数传进去:
>>> nums = [1, 2, 3]
>>> calc(*nums)
14
- 关键字参数** \*\*kw ** :0个或任意个含参数名的参数,这些关键字参数在函数内部自动组装为一个dict。
def person(name, age, **kw):
print 'name:', name, 'age:', age, 'other:', kw
#-----------------------------------------------------------------------
>>> person('Michael', 30)
name: Michael age: 30 other: {}
>>> person('Adam', 45, gender='M', job='Engineer')
name: Adam age: 45 other: {'gender': 'M', 'job': 'Engineer'}
- **参数组合**:参数定义的顺序必须是:必选参数、默认参数、可变参数和关键字参数。
def func(a, b, c=0, *args, **kw):
print 'a =', a, 'b =', b, 'c =', c, 'args =', args, 'kw =', kw
#-----------------------------------------------------------------------
>>> func(1, 2, c=3)
a = 1 b = 2 c = 3 args = () kw = {}
>>> func(1, 2, 3, 'a', 'b')
a = 1 b = 2 c = 3 args = ('a', 'b') kw = {}
>>> func(1, 2, 3, 'a', 'b', x=99)
a = 1 b = 2 c = 3 args = ('a', 'b') kw = {'x': 99}
-----------------------------------------------------------------------
args = (1, 2, 3, 4)
kw = {'x': 99}
func(*args, **kw)
a = 1 b = 2 c = 3 args = (4,) kw = {'x': 99}
对于任意函数,都可以通过类似**func(\*args, \*\*kw)**的形式调用它,无论它的参数是如何定义的。
9. ##### 递归与尾递归优化:
在函数返回的时候,调用自身本身,并且,return语句不能包含表达式。这样,编译器或者解释器就可以把尾递归做优化,使递归本身无论调用多少次,都只占用一个栈帧,不会出现栈溢出的情况
fact(n) = n! = 1 x 2 x 3 x ... x (n-1) x n = (n-1)! x n = fact(n-1) x n
用函数的方式表达
def fact(n):
if n==1:
return 1
return n * fact(n - 1)
尾递归的优化:
def fact(n):
return fact_iter(n, 1)
def fact_iter(num, product):
if num == 1:
return product
return fact_iter(num - 1, num * product)
上面的fact(n)函数由于return n * fact(n - 1)引入了乘法表达式,所以就不是尾递归了。要改成尾递归方式,需要多一点代码,主要是要把每一步的乘积传入到递归函数中:`return fact_iter(num - 1, num \* product)`仅返回递归函数本身,`num - 1`和`num\*product`在函数调用前就会被计算,不影响函数调用。