一些零散的python知识

lambda

lambda关键字表示匿名函数,常用于为map(),filter()等函数传入函数作为参数。例如:

>>> map(lambda x: x * x, [1, 2, 3, 4, 5, 6, 7, 8, 9])
[1, 4, 9, 16, 25, 36, 49, 64, 81]

冒号前的变量代表函数传入的参数,冒号后相当于函数体。匿名函数仅由一条语句组成。

也可以将匿名函数赋给一个变量,之后即可用此变量来调用函数,例如:

>>> f = lambda x, y: x+y
>>> f(3, 5)
8

赋值,copy()与deepcopy()

Eva_J小姐姐的博客对python的变量与内存的关系进行了详细的解释。简单来说,在python中将一个变量赋值给另一个变量即是两个变量指向了同一块存储变量值的内存空间,而对变量的初始化即是为变量开辟出一块新的内存空间。因此,对于基本数据类型(int, long, float, bool, str等)来说,将一个变量值赋给另一个变量,与为两个变量初始化相同值,在效果上并没有什么区别。
然而对于复杂数据类型,例如set, list, tuple, dict以及各种自定义类的对象,将变量a的值赋给变量b就相当于给a起了一个别名b,此时改变a的值,b的值也会同时改变,例如:

>>> a = [1,2,3]
>>> b = a
>>> a[1] = 4
>>> a
[1, 4, 3]
>>> b
[1, 4, 3]

对于自定义的类也是如此。因此将一个对象(列表/元组/..)直接赋值给另一个对象(列表/元组/..)并不能对原对象进行复制。要想实现复制操作,需要利用copy()或deepcopy()函数。
copy()和deepcopy()函数都是copy包中的函数,用于对对象进行复制,复制后新对象与原对象不会再互相影响。例如:

>>> import copy
>>> a = [1,2,3]
>>> b = copy.copy(a)     #此处使用deepcopy()效果相同
>>> a[1] = 4
>>> a
[1, 4, 3]
>>> b
[1, 2, 3]

copy()与deepcopy()的区别在于,利用copy()复制对象(列表/元组/..)时,内存为对象开辟了一块新的空间,然而对象的子对象依旧是原对象的子对象的别名。例如:

>>>import copy
>>> a = [[1,2,3], [4,5,6]]
>>> b = copy.copy(a)
>>> a[1] = [1,2,3]
>>> a
[[1, 2, 3], [1, 2, 3]]
>>> b
[[1, 2, 3], [4, 5, 6]]
>>> a[0][1] = 4
>>> a
[[1, 4, 3], [1, 2, 3]]
>>> b
[[1, 4, 3], [4, 5, 6]]

可以看出,虽然使用了copy()函数,在修改a中的子数组值时,b中子数组的值也会发生改变。要复制一个与原对象(列表/元组)完全独立的对象,应使用deepcopy(),例如:

>>> import copy
>>> a = [[1,2,3], [4,5,6]]
>>> b = copy.deepcopy(a)
>>> a[0][1] = 4
>>> a
[[1, 4, 3], [4, 5, 6]]
>>> b
[[1, 2, 3], [4, 5, 6]]

format()

format函数主要用于字符串的格式化,其中有一些trick用起来很是方便。

通过关键字构建字符串

>>> print 'This is {name} from {country}'.format(name='Alice', country='Canada')
This is Alice from Canada.

>>> student = {'name':'Alice', 'country':'Canada'}
>>> print 'This is {name} from {country}.'.format(**student)
This is Alice from Canada.

通过位置构建字符串

>>> print 'This is {0} from {1}.'.format('Alice', 'Canada')
This is Alice from Canada.

控制浮点数输出精度

>>> import math
>>> print '{:.2f}'.format(math.pi)
3.14

进制转换

>>> print('{:b}'.format(2))
10

生成器

python的生成器是一种特殊的迭代器。生成器支持在循环中不断计算后续的元素,从而节省存储空间。
对于列表生成式,只要把列表生成式中的[]改成()即可。

>>> (i for i in range(10))
<generator object <genexpr> at 0x7ff757c449b0>

为了从生成器中获得下一个值,我们利用next()函数:

>>> a = (i for i in range(10))
>>> a
<generator object <genexpr> at 0x7ff757c44820>
>>> a.next()
0

另一种更常用的方法是使用for循环来对生成器进行迭代:

>>> a = (i for i in range(10))
>>> for i in a: print i
... 
0
1
2
3
4
5
6
7
8
9

生成器只能进行一次遍历,在调用next()函数到列表末尾时,会抛出StopIteration错误。

除了列表生成式,还可以用一个函数来实现生成器。生成器和普通函数的区别是,当它要生成一个值的时候使用yield关键字而不是return。

def fib(maxNum):
        n, a, b = 0, 0, 1
        while n < maxNum:
                yield b
                a, b = b, a+b
                n += 1

gen = fib(6)
for i in gen:
        print i

执行结果:

1
1
2
3
5
8

变成generator的函数,在每次调用next()的时候执行,遇到yield语句返回,再次执行时从上次返回的yield语句处继续执行。

def fib(maxNum):
        n, a, b = 0, 0, 1
        while n < maxNum:
            print 'haha'
                yield b
                a, b = b, a+b
                n += 1

gen = fib(6)
for i in gen:
        print i

执行结果:

haha
1
haha
1
haha
2
haha
3
haha
5
haha
8

类的私有变量

在类中的变量或函数前加“__”就能够将变量或函数变成私有变量/私有函数。

  • 私有变量在子类中和外部均不可直接访问。

猜你喜欢

转载自blog.csdn.net/m0_37924639/article/details/80006362