21. 列出 python 中可变数据类型和不可变数据类型,并简述原理

Python 中一切皆对象,对象就像一个塑料盒子,里面装的是数据。对象有不同类型,例如布尔型和整型,类型决定了可以对它进行的操作。现实生活中的"陶器"会暗含一些信息(例如它可能很重且易碎,注意不要掉到地上)。 对象的类型还决定了它装着的数据是允许被修改的变量(可变的 mutable)还是不可被修改的常量(不可变的 immutable)。你可以把不可变对象想象成一个透明但封闭的盒子:你可以看到里面装的数据,但是无法改变它。类似地,可变对象就像一个开着口的盒子,你不仅可以看到里面的数据,还可以拿出来修改它,但你无法改变这个盒子本身,即你无法改变对象的类型。

  • mutable:可变对象,如 List、Dict 和 Set
  • immutable:不可变对象,如 Number、String、Tuple、Frozenset

注意:

Python 赋值操作或函数参数传递,传递的永远是对象引用(即内存地址),而不是对象内容。

In [1]: a = 1
In [2]: b = a

In [3]: id(a)
Out[3]: 9164864
In [4]: id(b)
Out[4]: 9164864

In [5]: b += 1
In [6]: a
Out[6]: 1
In [7]: b
Out[7]: 2
In [8]: id(a)  # 对象引用a还是指向Number对象1
Out[8]: 9164864
In [9]: id(b)  # 对象引用b指向了Number对象2
Out[9]: 9164896

Python 会缓存使用非常频繁的小整数-5 至 256 、 ISO/IEC 8859-1 单字符 、 只包含大小写英文字 母的字符串 ,以对其复用,不会创建新的对象:

1. 不会创建新对象 In [1]: a = 10
In [2]: b = 10
In [3]: id(a)
Out[3]: 9165152
In [4]: id(b)
Out[4]: 9165152
In [5]: a = '@'
In [6]: b = '@'
In [7]: id(a)
Out[7]: 139812844740424
In [8]: id(b)
Out[8]: 139812844740424
In [9]: a = 'HELLOWORLDhelloworld'
In [10]: b = 'HELLOWORLDhelloworld'
In [11]: id(a)
Out[11]: 139812785036792
In [12]: id(b)
Out[12]: 139812785036792
2. 会创建新的对象
In [1]: a = 1000
In [2]: b = 1000
In [3]: id(a)
Out[3]: 140528314730384
In [4]: id(b)
Out[4]: 140528314731824
In [5]: a = 'x*y'
In [6]: b = 'x*y'
In [7]: id(a)
Out[7]: 139897777405880
In [8]: id(b)
Out[8]: 139897777403808
In [9]: a = 'Hello World'
In [10]: b = 'Hello World'
In [11]: id(a)
Out[11]: 139897789146096
In [12]: id(b)
Out[12]: 139897789179568

上述测试必须早交互式环境下操作,编译环境下会做优化。

copy 是浅拷贝 (只拷贝内存地址)

deepcopy 是深拷贝 (内容重新分配)

22. 字符串基操

s = "ajldjlajfdljfddd",去重并从小到大排序输出"adfjl"

s = "ajldjlajfdljfddd"
s = list(set(s))
s.sort(reverse=False)
ret = "".join(s)
print(ret)

out:

adfjl

首先去重是利用的集合,

然后转成数组才能 sort,reverse

然后还要拼接成字符串。

23. Lambda 函数

用 lambda 函数实现两个数相乘

sum = lambda a, b: a * b
print(sum(5, 4))

out:

20

主要是理解 lambda 的写法,lambda 是匿名函数(可以这么理解)

后面用逗号隔开参数,冒号后面写返回值。可以是复杂的列表推导式,但是只能是“一句话”。

24. 字典根据键值从小到大排序

dic={"name":"zs","age":18,"city":"深圳","tel":"1362626627"}

dic = {"name": "zs", "age": 18, "city": "深圳", "tel": "1362626627"}

lis = sorted(dic.items(), key=lambda i: i[0], reverse=False)

print(lis)

lis = dict(lis)

print(lis)

out:

[('age', 18), ('city', '深圳'), ('name', 'zs'), ('tel', '1362626627')] {'age': 18, 'city': '深圳', 'name': 'zs', 'tel': '1362626627'}

先使用 sorted 函数根据键值进行排序。

然后转成字典。

25. collections 库

利 用 collections 库 的 Counter 方 法 统 计 字 符 串 每 个 单 词 出 现 的 次数

"kjalfj;ldsjafl;hdsllfdhg;lahfbl;hl;ahlf;h"

from collections import Counter

string = "kjalfj;ldsjafl;hdsllfdhg;lahfbl;hl;ahlf;h"

res = Counter(string)

print(res)

没啥好说的。。。

26. 再来正则

字符串 a = "not 404 found 张三 99 深圳",每个词中间是空格,用正则过滤掉英 文和数字,终输出"张三 深圳"

import re

a = "not 404 found 张三 99 深圳"
list = a.split(" ")
print(list)
res = re.findall(r'\d+|[a-zA-Z]+', a)

for i in res:
    if i in list:
        list.remove(i)
new_str = " ".join(list)

print(res)
print(new_str)

out:

['not', '404', 'found', '张三', '99', '深圳'] ['not', '404', 'found', '99'] 张三 深圳

使用\d匹配数字,[a-zA-Z]匹配英文字符

+表示 1 或任意个,|表示多个匹配规则

匹配小数的话

\d+\.?\d*

不一定对。

27. filter 方法

filter 方法求出列表所有奇数并构造新列表,a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]


def fn(a):
    return a % 2 == 1


newList = filter(fn, a)
print(newList)
newList = [i for i in newList]
print(newList)

out:

<filter object at 0x00000172B4E1F5C8> [1, 3, 5, 7, 9]

filter() 函数用于过滤序列,过滤掉不符合条件的元素,返回由符合条件元素组成的新列 表。该接收两个参数,第一个为函数,第二个为序列,序列的每个元素作为参数传递给函数进行判断,然后返回TrueFalse,最后将返回True的元素放到新列表。

filter 返回的是迭代器。所以要组装成列表。

28. 列表推导式

列表推导式求列表所有奇数并构造新列表,a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

res = [i for i in [x for x in range(1, 11)] if i % 2 == 1]
print(res)

构造列表只要在两边加[]就可以啦。

29. re.compile()

re.compile()是将正则表达式编译成一个对象,加快速度,并重复使用

就是将你的正则表达式搞成一个对象存着了。

30. tuple 的小小的坑

a=(1,)b=(1),c=("1") 分别是什么类型的数据?

print(type((1)))
print(type(("1")))
print(type((1,)))

out:

<class 'int'> <class 'str'> <class 'tuple'>

()是运算符,是运算符,是运算符。

重要的事情说三遍。但是在创建tuple的时候

如果需要创建只有一个元素的tuple,那么要加逗号,