31、函数传参,既不是传值也不是传引用
结论:是传对象!
对不可变类型(数字、字符串及元组),由于对象并不能真正被修改,因此对象值的修改的过程是通过生成一个新的对象然后赋值完成。
对可变类型(字典、列表、字节数组),对可变对象的修改是在函数外部内部均可见的,调用者和被调用者共享这个对象。
.注:个人的理解,python在这一点上与C++不同,需要开发人员在编程的时候时刻小心,一不小心,对象的值就可能”面目全非“。
下面的代码:
>>> a = 5 #先开辟一块存储5这个值的内存,将a这个变量(对象)指向这块内存
>>> id(a)
140494650783752
>>> b = a #将b这个变量指向和a一样的内存空间
>>> id(b)
140494650783752
>>> b = 7
>>> id(b)
140494650783704
>>> id(a)
140494650783752
其实际的赋值模型见下面的示意图。
37、按需选择sort()或者sorted()
- 语法
sorted(iterable[,cmp[,key[,reverse]]])
s.sort([cmp[,key[,reverse]]])
"""
cmp:是用户定义的任何比较函数,函数的参数为两个可比较的元素,函数根据第一个与第二个参数的关系,一次返回-1, 0 或者 +1(第一个参数效益第二个参数返回负数),该参数默认值为None
key:是一个带参数的函数,用来为每个元素提取比较值,默认是None(即直接比较每个元素)
- sorted()函数可用于任何可迭代对象,而sort一般用于列表;
- sorted()返回一个排序后的列表,而原列表不变,sort()方法直接修改原有列表,返回值为None;
- sorted()函数功能更为强大
- 可以对字典进行排序
>>> phonebook = {'Linda':'7750', 'Bob':'9345', 'Carol':'5834'}
>>> from operator import itemgetter
>>> sorted_pb = sorted(phonebook.iteritems(), key = itemgetter(1))
>>> print (sorted_pb)
[('Carol', '5834'), ('Linda', '7750'), ('Bob', '9345')]
- 可以对多维list进行排序
>>> from operator import itemgetter
>>> gameresult = [['Bob', 95.00, 'A'], ['Alan', 86.0, 'C'], ['Mandy', 82.5, 'A'], ['Rob', 86, 'E']]
>>> sorted(gameresult, key = itemgetter(2, 1))
[['Mandy', 82.5, 'A'], ['Bob', 95.0, 'A'], ['Alan', 86.0, 'C'], ['Rob', 86, 'E']]
- 可以对字典中混合list排序
>>> mydict = {'Li':['M', 7], 'Zhang':['E',2], 'Wang':['P',3], 'Du':['C',2], 'Ma':['C',9], 'Zhe':['H',7]}
>>> from operator import itemgetter
>>> sorted(mydict.iteritems(), key = lambda (k,v):itemgetter(1)(v))
[('Zhang', ['E', 2]), ('Du', ['C', 2]), ('Wang', ['P', 3]), ('Li', ['M', 7]), ('Zhe', ['H', 7]), ('Ma', ['C', 9])]
注:对上面代码的理解:
1)mydict.iteritems() 将字典mydict的内容以列表的形式返回,返回一个迭代器;
2)lambda (k,v):itemgetter(1)(v)),定义一个匿名函数,这个函数的输入参数是一个列表(即mydict.iteritems() ),列表的元素对应变量k和v,例如(‘Li’, [‘M’, 7]),其中,k对应key(‘Li’),v对应value([‘M’, 7]),参考元组拆包。
3)lambda函数的函数体,首先“定义”了一个“函数” itemgetter(1),即取得指定对象位置为1的元素,为了便于理解,给这个函数起个名字fun_itemgetter,然后,itemgetter(1)(v) 相当于fun_itemgetter(v),即取得对象v的位置为1的元素作为排序的关键字!这下子明白了吧?!
多说一句,有时候觉得这种所谓的Pythonic代码,很难理解,可能是我水平有限吧,但过于优美的代码,是不是意味着不好理解呢?
- 可以对list中混合字典进行排序
>>> gameresult = [{'name':'Bob', 'wins':10, 'losses':3, 'rating':75.00}, {'name':'david', 'wins':3, 'losses':5, 'rating':57.00}, {'name':'Carol', 'wins':4, 'losses':5, 'rating':57.00}, {'name':'Patty', 'wins':9, 'losses':3, 'rating':71.48}]
>>> from operator import itemgetter
>>> sorted(gameresult, key = itemgetter('rating', 'name'))
[{'wins': 4, 'losses': 5, 'name': 'Carol', 'rating': 57.0}, {'wins': 3, 'losses': 5, 'name': 'david', 'rating': 57.0}, {'wins': 9, 'losses': 3, 'name': 'Patty', 'rating': 71.48}, {'wins': 10, 'losses': 3, 'name': 'Bob', 'rating': 75.0}]
*** 学习 from operator import itemgetter ***
以下文字来自:Python operator.itemgetter函数理解
作用:itemgetter 用于获取对象的哪些位置的数据,参数即为代表位置的序号值,
注:这里其他参考资料上’位置’描述的词语是’维度’,我和其他人想法不同,不能称之为维度,准确的描述,应该是位置,因为我发现,itemgetter返回的只是下标,并且只将处理对象看做一维的,详细可以看后面例子的描述
注意:itemgetter 获取的不是值,而是定义了一个函数,通过该函数作用到目标对象上,取出目标对象对应维度的值
例如:
a = [1,2,3]
b = [[1,2,3],[4,5,6],[7,8,9]]
注: Python列表、元祖、字典等对象的下标均是从0开始的
这里描述一下我理解的维度,即从线性代数的角度看:
这里,列表a我们可以看做一维数据,上面3个点:a[0] = 1, a[1] = 2, a[2] = 3
列表b则是2维数据,上面是9个点:b[0,0] = 1, b[0,1] = 2, b[0,2] = 3, b[1,0] = 4, …, b[2,2] = 9
理解了上面的描述,就可以更好的理解itemgetter的处理结果了
我们定义取出对象位置1上的数据:
>>> get_1 = itemgetter(1)
>>> get_1(a)
2
>>> get_1(b)
[4,5,6]
类似:取出对象1,2位置上的数据,并且调整一下顺序:
>>> get_21 = itemgetter(2,1)
>>> get_21(a)
[3,2]
>>> get_21(b)
[[7,8,9],[4,5,6]]
如果要取出b中第2维度上相应位置上的数据,则需要对其中各个子列表进行取数,因为itemgetter的对象是1维对象:
>>>b_21 = []
>>>for temp in b:
tep = get_21(temp)
b_21.append(tep)
# 也可以直接:b_21 = [get_21(temp) for temp in b]
b_21 = [[3,2],[6,5],[9,8]]
*** 学习lambda函数的基本知识 ***
以下文字来自:python – lambda表达式
lambda表达式,通常是在需要一个函数,但是又不想费神去命名一个函数的场合下使用,也就是指匿名函数。
lambda所表示的匿名函数的内容应该是很简单的,如果复杂的话,干脆就重新定义一个函数了,使用lambda就有点过于执拗了。
lambda就是用来定义一个匿名函数的,如果还要给他绑定一个名字的话,就会显得有点画蛇添足,通常是直接使用lambda函数。如下所示:
add = lambda x, y : x+y
add(1,2) # 结果为3
那么到底要如何使用lambda表达式呢?
1、应用在函数式编程中
Python提供了很多函数式编程的特性,如:map、reduce、filter、sorted等这些函数都支持函数作为参数,lambda函数就可以应用在函数式编程中。如下:
需求:将列表中的元素按照绝对值大小进行升序排列
list1 = [3,5,-4,-1,0,-2,-6]
sorted(list1, key=lambda x: abs(x))
当然,也可以如下:
list1 = [3,5,-4,-1,0,-2,-6]
def get_abs(x):
return abs(x)
sorted(list1,key=get_abs)
只不过这种方式的代码看起来不够Pythonic