难度指数: ★
重要指数: ★★
随机数相关的模块是random模块, 三个方法分别提供随机整数,随机0到1之间的小数和任意两个数之间的小数
import random
print(random.randint(0, 10)) # 生成随机整数 [a, b] 左闭右闭
print(random.random()) # 生成[0, 1) 之间的小数
print(random.uniform(3.2, 6.7)) # 生成[a, b] 之间的小数
唯一的需要关注的是生成随机数的范围,中括号表示闭, 小括号表示开,[a, b)表示左闭右开,表示结果可以为a, 但一定不会为b,a <= 随机结果 < b
难度指数: ★
重要指数: ★★
难度指数: ★
重要指数: ★★
题目要求
有字典dic,内容为
dic = {1:3, 2:2, 3:1}
根据键进行排序,其结果为 [(2, 7), (3, 1), (5, 3)], 根据value进行排序,其结果为[(3, 1), (5, 3), (2, 7)]
字典本身是无序的,python3与2不同,python3的字典在遍历时,可以根据写入key-value对的顺序进行遍历。题目的要求是获得一个列表,列表里的元素都是元组,元组的第一个元素是key, 第二个元素是value,对序列排序,就要用最强大的sorted函数
dic = {5:3, 2:7, 3:1}
sort_by_key = sorted(dic.items(), key=lambda x: x[0])
sort_by_value = sorted(dic.items(), key=lambda x: x[1])
print(sort_by_key) # [(2, 7), (3, 1), (5, 3)]
print(sort_by_value) # [(3, 1), (5, 3), (2, 7)]
难度指数: ★★
重要指数: ★★★
题目要求:
字符串a = "not 404 found 张三 99 深圳",每个词中间是空格,用正则过滤掉英文和数字,最终输出"张三 深圳"
正则表达式也是面试中经常被问到的问题,对于这个题目,有好几种方法,你都应当掌握
import re
s = "not 404 found 张三 99 深圳"
pattern = re.compile("[\u4e00-\u9fa5]+")
lst = pattern.findall(s) # ['张三', '深圳']
print(" ".join(lst))
在unicode中汉字的编码是连续的,从\u4e00到\u9fa5, [\u4e00-\u9fa5] 表示汉字中的某一个,后面的加号表示1或n个, 这样就可以匹配到连续的汉字,findall以列表的形式返回匹配的汉字,最后使用空格连接。
import re
s = "not 404 found 张三 99 深圳"
pattern = re.compile("[0-9a-zA-Z]")
string = pattern.sub("", s)
print(" ".join(string.split()))
[0-9a-zA-Z]匹配所有数字和字母,sub方法会将正则表达式匹配的部分替换成空字符串,得到string并不是最终想要的结果,因为原来的数字和字母部分都替换成了空字符串,留下了很多空格,使用split函数切分后得到['张三', '深圳'], 再用空格连接。
import re
s = "not 404 found 张三 99 深圳"
pattern = re.compile("[\d+|(a-z)+\s+]")
lst = pattern.split(s) # ['', '', '', '', '', '', '', '', '', '', '', '', '', '', '张三', '', '', '', '深圳']
lst = [item for item in lst if item] # ['张三', '深圳']
print(" ".join(lst))
使用数字,字母,空格做分隔符切分字符串,会得到很多空字符串,对他们进行一次过滤,再用空格连接
import re
s = "not 404 found 张三 99 深圳"
pattern = re.compile("\d+|[a-zA-Z]+")
lst = pattern.findall(s) # ['not', '404', 'found', '99']
result = s.split() # ['not', '404', 'found', '张三', '99', '深圳']
result = list(set(result).difference(set(lst))) # ["张三", "深圳"]
print(" ".join(result))
难度指数: ★
重要指数: ★★
题目要求:
利用collections库的Counter方法统计字符串每个字符出现的次数”kjalfj;ldsjafl;hdsllfdhg;lahfbl;hl;ahlf;h”
这是一个送分题目,不需要你编写任何算法,能正确使用Counter 就可以了
from collections import Counter
a = "kjalfj;ldsjafl;hdsllfdhg;lahfbl;hl;ahlf;h"
res = Counter(a)
print(res) # Counter({'l': 9, ';': 6, 'h': 6, 'f': 5, 'a': 4, 'j': 3, 'd': 3, 's': 2, 'k': 1, 'g': 1, 'b': 1})
难度指数: ★
重要指数: ★★
题目要求:
filter方法求出列表所有奇数并构造新列表,a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
filter用于过滤数据,但filter返回的是一个生成器,题目要求构造新列表,这一点审题要注意
a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
lst = [item for item in filter(lambda x: x % 2 == 1, a)]
print(lst)
难度指数: ★
重要指数: ★★
python的os.remove可以删除文件,但在删除前,应当使用os.path.exists()函数判断一下文件是否存在,不存在时调用remove函数删除会引发文件不存在的异常。
如果要删除文件夹,可以使用os.removedirs函数,但该函数只能删除空的文件夹,想要删除一个不空的文件夹,可以使用shutil.rmtree(path) 函数来进行删除。
linux系统里,使用rm 可以删除文件,如果想要删除文件夹,使用rm -rf 命令,这样即便文件夹非空,也可以删除。
难度指数: ★★★
重要指数: ★★★
(.*) 是贪婪匹配,会把满足正则的尽可能多的往后匹配
(.*?) 非贪婪匹配,会把满足正则的尽可能少匹配
举个例子进行说明
import re
pattern_1 = re.compile("{(.*)}")
pattern_2 = re.compile("{(.*?)}")
string = "{hello} {world}"
result_1 = pattern_1.findall(string)
result_2 = pattern_2.findall(string)
print(result_1) # ['hello} {world']
print(result_2) # ['hello', 'world']
使用贪婪匹配时,遇到第一个左大括号,会向后一直寻找最后一个右大括号,而使用非贪婪匹配,找到第一个右大括号就算匹配上。
难度指数: ★
重要指数: ★★
题目要求:
x="abc",y="def",z=["d","e","f"],分别求出x.join(y)和x.join(z)返回的结果
这是一道铁铁的送分题目,只要了解join方法的作用就能答得出来。唯一的一个小麻烦在于,你平时所见的都是用某个字符串去连接列表里的字符串,但变量y是一个字符串啊。
这就是理解的还不够深入,字符串的join方法,所能传入的数据并不只是列表,而是iterable, 可迭代对象,字符串也是可迭代对象,对字符串y进行迭代,得到的是单个字母,把这些字母用x连接起来就是最终结果,因此两个写法的最终结果是一致的,都是dabceabcf, x.join(y) 等价于下面的代码
s = ""
for item in y:
s += item + x
print(s[:-len(x)]) # dabceabcf
难度指数: ★
重要指数: ★★
zip函数是一个非常拥有的函数,它可以将多个可迭代对象作为参数,将对象中对应的元素打包成元组,如果可迭代对象的长度不同,则根据长度最短的那个进行打包。
举例说明
lst1 = [1, 2, 3, 4, 5]
lst2 = ['一', '二', '三', '四', '五']
如果要将上面的两个列表整合成一个字典
{1: '一', 2: '二', 3: '三', 4: '四', 5: '五'}
采用普通方法的算法是这样的
lst1 = [1, 2, 3, 4, 5, 6]
lst2 = ['一', '二', '三', '四', '五']
info = {}
for index, item1 in enumerate(lst1):
if index < len(lst2):
info[item1] = lst2[index]
print(info)
for循环一次只能遍历其中一个列表,但使用zip就可以同时遍历这两个列表
lst1 = [1, 2, 3, 4, 5, 6]
lst2 = ['一', '二', '三', '四', '五']
info = {}
for item1, item2 in zip(lst1, lst2):
info[item1] = item2
print(info)
代码是不是清爽了许多,你想更加清爽,可以使用字典推导式
lst1 = [1, 2, 3, 4, 5, 6]
lst2 = ['一', '二', '三', '四', '五']
info = {item1: item2 for item1, item2 in zip(lst1, lst2)}
print(info)
难度指数: ★
重要指数: ★★
举例说明
print(any([False, 6 > 3, '', 8])) # 结果是True, 因为6 > 3 结果为True,8 等价于True
print(all([8 > 4, True, ''])) # 结果是False, 因为 空字符串等价于False
难度指数: ★
重要指数: ★★
难度指数: ★★★
重要指数: ★★
题目要求:
使用sorted 进行排序对list排序foo =[-5,8,0,4,9,-4,-20,-2,8,2,-4],正数从小到大,负数从大到小, 最终结果为
[0, 2, 4, 8, 8, 9, -2, -4, -4, -5, -20]
这是一道比较考验功力的题目,只有真正理解sorted用法的人才能回答得出,我先放出答案,再解释原理
foo =[-5, 8, 0, 4, 9, -4, -20, -2, 8, 2, -4]
result = sorted(foo, key=lambda x: (x < 0, abs(x)))
print(result)
你或许在网上也看到了类似的答案,但是并没有人详细解释为什么这么做是有效果的。首先我们要弄清楚sorted排序的原理,它的key究竟是要起什么作用。如果列表里的数据都是int,那么几乎就用不到key,因为int与int之间能够进行大比较,但如果列表里的元素是那种无法确定比较大小方法的数据呢?比如下面的数据
lst = [(5, 2), (1, 6)]
请问,到底是(5, 2) 大,还是(1, 6) 大? 如果以元组第一个元素来比较那么(5, 2)大,如果以元组第二个元素来比较大小,则(1, 6)大,到底用哪个来比较大小呢,这个时候就可以用key来决定了
lst = [(5, 2), (1, 6)]
print(sorted(lst, key=lambda x: x[0])) # 用元组第一个元素进行大小比较 [(1, 6), (5, 2)]
print(sorted(lst, key=lambda x: x[1])) # 用元组第二个元素进行大小比较 [(5, 2), (1, 6)]
如果不指定key呢,默认会使用元组第一个元素进行大小比较。关于key,我们还可以换一种方法来理解,如果以元组的第二个元组进行大小比较,就相当于说,2 代表(5, 2),6 代表(1, 6) 进行比较。
回头来看 lambda x: (x < 0, abs(x)) , 当x的 -5 时,lambda的返回值是元组(True, 5), 当x = 8 时,lambda的返回值是元组(False, 8), (True, 5) 代表-5 ,(False, 8)代表8 进行大小比较,两个元组进行大小比较,默认用元组的第一个元素进行比较,False等价于0, True等价于1, 比较的结果是8 小于 -5 ,注意,8是比-5大的,但是我们让(False, 8)代表8与代表-5 的 (True, 5) 进行比较,所以结果上,8 比 -5 小。
当元组第一个元素相同时,则使用元组的第二个元素继续比较,最终就得到了我们想要的结果
难度指数: ★★
重要指数: ★★
题目要求:
分别根据年龄和姓名排序 foo = [{"name":"zs","age":19},{"name":"ll","age":54}, {"name":"poly","age":22}]
经过8.13题目的洗礼,sorted函数的用法应当已经掌握了,我这里直接给出答案
foo = [{"name":"zs","age":19},{"name":"ll","age":54}, {"name":"poly","age":22}]
result = sorted(foo, key=lambda x: x['name']) # 以姓名排序
print(result) # [{'name': 'll', 'age': 54}, {'name': 'poly', 'age': 22}, {'name': 'zs', 'age': 19}]
result = sorted(foo, key=lambda x: x['age']) # 以年龄排序
print(result) # [{'name': 'zs', 'age': 19}, {'name': 'poly', 'age': 22}, {'name': 'll', 'age': 54}]
难度指数: ★★
重要指数: ★★★★
字典与json字符串的转换要用json模块,是必须掌握的知识点,工作中,会大量的使用对象的序列化与反序列化操作
import json
data = {"name": 'python'}
# 字典转json字符串
json_str = json.dumps(data)
print(json_str)
# json字符串转字典
data = json.loads(json_str)
print(data)
字典转json字符串要用json.dumps函数,json字符串转字典用json.loads函数
这个问题,仅仅回答到这里是不够的,还要回答如何将字典保存到文件中,又如何从文件中加载数据转为字典
import json
data = {"name": 'python'}
with open('data', 'w')as f:
json.dump(data, f)
with open('data', 'r')as f:
data = json.load(f)
print(data, type(data))
将对象序列化到文件中,使用json.dump()函数, 从文件读取数据反序列化使用jons.load()函数。
难度指数: ★★
重要指数: ★★★
这个题目考察的是对文件读写模式的理解
文件打开模式
难度指数: ★★
重要指数: ★★
举例说明
import re
string = "hello word"
print(re.match('hell', string)) # <_sre.SRE_Match object; span=(0, 4), match='hell'>
print(re.match('word', string)) # 虽然word存在,但不是在开头, 返回None
print(re.search('hell', string)) # <_sre.SRE_Match object; span=(0, 4), match='hell'>
print(re.search('word', string)) # <_sre.SRE_Match object; span=(6, 10), match='word'>
难度指数: ★
重要指数: ★★
python的变量是没有类型的,变量只是对象的引用,尽管现在有类型标注,但在调试程序的过程中,仍然不能方便的确定变量所引用对象的类型。你可以使用type函数来查看一个变量的类型,这有助于你理解程序,但如果使用了第三方库,第三方库返回的对象就是你不熟悉的对象,如果没有详细的文档,你甚至不知道这个对象有什么属性,有什么方法,这个时候就可以使用dir函数来查看
class T:
def __init__(self, name):
self.name = name
def run(self):
print('run')
t = T('小明')
print(dir(t)) # [.... 'name', 'run']
dir会返回对象t所拥有的属性和方法名称,其中有很多都是以双下滑线开头的,我们要关注那些不带双下划线的。
难度指数: ★★
重要指数: ★★★★
字符串格式化,是使用频率非常高的技术,主要有三种方法
举例说明
name = "小明"
age = 14
str_format = "%s今年%d岁了"
print(str_format % (name, age))
str_format = "{name}今年{age}岁了"
print(str_format.format(name=name, age=age))
print(f"{name}今年{age}岁了")
三种方法里,使用% 是最初级的,也是不建议使用的,format方法相比于% 要高级一些,不过f-string才是当前格式化字符串的最佳选择
难度指数: ★★
重要指数: ★★
read 和 readlines 都是读取所有数据,如果文件非常大,不建议使用这两个方法来读取数据,readline会读取一行数据,因此不会占用内存,当文件很大时,应当使用readline,除了这三个方法以外,我更推荐对文件对象进行遍历
from collections import Iterable
with open('data', 'r')as f:
print(isinstance(f, Iterable)) # True f是可迭代对象
for line in f:
print(line.strip())
打开的文件对象f是可迭代对象,直接对其使用for循环迭代更加方便
QQ交流群: 211426309