最新12(1),2024年最新大数据开发面试八股文

img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上大数据知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

需要这份系统化资料的朋友,可以戳这里获取


#### ⑩list.reverse()


* 反向列表中元素


#### ⑩①list.sort([func])


* 对原列表进行排序


#### ⑩②列表操作中还有深浅复制的方法


* 具体看这篇文详解——[一节课让你彻底搞懂python里面试最常问问题之一深浅复制——看完不懂你来揍我!(三好学生都已经拿出笔记本认真上课记笔记了~)](https://bbs.csdn.net/topics/618545628)


#### 拓展:列表排序的方法!



①sort() —>对列表里的数值从小到大排序,只能是数字,如果列表里有字符串的话那么需要在括号内加入:key=str 如a.sort(key=str) 。字符串的排序根据于ASCII的字母排序。
上代码:
a = [‘a’, ‘d’, ‘f’, ‘b’]
a.sort(key=str)
print(a) # 输出为:[‘a’, ‘b’, ‘d’, ‘f’]

拓展:使用sort()方法对列表里的数值从大到小排序;如果列表里有字符串的话加入参数key=str,如a.sort(key=str,reverse=True)。
上代码:(列表含有字符串)
a = [‘a’, ‘g’, ‘b’, ‘c’]
a.sort(key=str,reverse=True)
print(a) # 输出为:[‘g’, ‘c’, ‘b’, ‘a’]

上代码:(列表元素都是数字)
a = [1,9,3,7]
a.sort(reverse=True)
print(a) # 输出为:[9,7,3,1]

②reverse() —>对列表里的数值从大到小反序,只能是数字。
上代码:
a = [1, 4, 3, 8]
a.reverse()
print(a) # 输出为: [8,3,4,1]


## 一些在项目中常用的列表小操作!


### (1)找出列表中出现次数最多的元素


如果有一天,同学们在工作,Boss突然抛出来一个需求:\*\*在python程序中如何找到列表中出现次数最多的元素!\*\*难道你要使用循环啥的一步步瞎搞?效率低B格也不高。这里为师教你们一种简单易上手B格高的方法——**使用collections模块中的Counter类,调用Counter类中的most\_common()函数来实现!**  
 **直接上代码:**



from collections import Counter
words = [
‘look’, ‘into’, ‘my’, ‘AAA’, ‘look’, ‘into’, ‘my’, ‘AAA’,
‘the’, ‘AAA’, ‘the’, ‘eyes’, ‘not’, ‘BBB’, ‘the’, ‘AAA’,
“don’t”, ‘BBB’, ‘around’, ‘the’, ‘AAA’, ‘look’, ‘into’,
‘BBB’, ‘AAA’, ‘BBB’, ‘under’
]

word_counts = Counter(words)
print(‘统计所有元素出现次数:’,word_counts)
top_three = word_counts.most_common(3)
print(‘统计出现次数最多的三个元素:’,top_three)



输出为:
统计所有元素出现次数: Counter({‘AAA’: 6, ‘the’: 4, ‘BBB’: 4, ‘look’: 3, ‘into’: 3, ‘my’: 2, ‘eyes’: 1, ‘not’: 1, “don’t”: 1, ‘around’: 1, ‘under’: 1})
统计出现次数最多的三个元素: [(‘AAA’, 6), (‘the’, 4), (‘BBB’, 4)]


### (2)排序类定义的实例


项目背景:**如果我们在一个项目中,一个类定义的实例有很多个,而我们的需求是将这些实例排序该怎么做呢?**


**使用内置函数sorted()可以接收一个用来传递可调用(callable)对象的参数key,而这个可调用对象会返回待排序对象中的某些值,sorted()函数则利用这些值来比较对象。**


假如在程序中存在多个User对象的实例,如果想通过属性user\_id来对这些实例进行排序,可以提供一个可调用对象,它将User实例作为输入,然后返回user\_id。下面代码演示排序上述User对象实例的过程:



class User:
def __init__(self, user_id):
self.user_id = user_id

def \_\_repr\_\_(self):
    return 'User({})'.format(self.user_id)

原来的排序

users = [User(91), User(17), User(18)]
print(users)

根据user_id排序——两种方法

①使用lambda表达式:

print(sorted(users, key=lambda u: u.user_id))

②使用内置函数operator.attrgetter()进行处理:

from operator import attrgetter
print(sorted(users, key=attrgetter(‘user_id’)))


![在这里插入图片描述](https://img-blog.csdnimg.cn/20210622205903212.png)


### (3)命名切片(高阶用法)


项目问题背景:  
 在python程序中,有时会发现编写的代码由于过度的使用硬编码的切片索引(就像上面第二小节课讲的那样!),而使得我们的项目代码变得杂乱无章而无法阅读,此时就需要清理它们。同时过度的使用硬编码的索引值,也会降低代码的可读性和可维护性。


解决方法:  
 **在python程序中,使用函数slice()可以实现切片对象,能够在切片操作函数中实现参数传递功能,可以被用在任何允许进行切片操作的地方。**



使用函数slice()的语法格式:
class slice(stop)
class slice(start, stop, step)

start:起始位置;
stop:结束位置;
step:间距。


上代码讲解:



items = [0, 1, 2, 3, 4, 5, 6]

a = slice(2,4) # 定义一个slice对象实例a

print(items[2:4]) # 使用常用的切片取列表值
print(items[a]) # 使用slice对象实例a取列表值

items[a] = [10, 11]
print(items)

print(a.start) # 分别通过属性a.start,a.stop,a.step获取该slice对象的信息
print(a.stop)
print(a.step)

s = ‘verygoodman’

使用indices(size)函数将切片映射到特定大小的序列上,这将会返回一个(start,stop,step)元组,

所有的值都已经正好限制在边界以内,这样当进行索引操作时可以避免出现IndexError异常。

print(a.indices(len(s)))
print(*a.indices(len(s))) # 分解元组
for i in range(*a.indices(len(s))):
print(s[i])


![在这里插入图片描述](https://img-blog.csdnimg.cn/20210622212416438.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQ0OTA3OTI2,size_16,color_FFFFFF,t_70)


**深入讲解——使用indices(size)函数的好处,以及上述注释中写的为何使用此函数当进行索引操作时可以避免出现IndexError异常!**  
 **直接上代码讲解:**



a = slice(2,4) # 定义一个slice对象实例a

s = ‘ver’ # 此时序列s

使用indices(size)函数将切片映射到特定大小的序列上,这将会返回一个(start,stop,step)元组,

所有的值都已经正好限制在边界以内,这样当进行索引操作时可以避免出现IndexError异常。

print(a.indices(len(s)))
print(*a.indices(len(s))) # 分解元组
for i in range(*a.indices(len(s))):
print(s[i])


**[一节课让你彻底搞懂python中的单星号(\*)和双星号(\*\*)的区别及项目实际用法——给我学!](https://bbs.csdn.net/topics/618545628)**


**观察运行结果会发现:我们虽然定义的slice对象实例的切片范围是2-4,但是由于映射到的序列整体范围只有0-3(左闭右开),因为我们使用了indices(size)函数,它会将切片范围限制在这个映射的序列范围边界以内:2-3,这样虽然我们定义的slice对象实例范围超出了此序列s的范围,但是因为indices(size)函数的使用并不会报错,而是类似于动态的自适应变化!**  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20210622214031241.png)


### (4)生成list相关函数(重点!!!!)


#### 一、列表生成式


列表推导式(List Comprehension)是一种简化代码的优美方法。官方文档——**列表推导式提供了一种创建列表的简洁方法。** 使用列表推导式能够非常简洁的构造一个新列表,只需要用一个简洁的表达式即可对得到的元素进行转换变形。



使用Python列表推导式的语法格式:

variable = [out_exp_res for out_exp in input_list if out_exp == 2]

out_exp_res:列表生成元素表达式,可以是有返回值的函数;
for out_exp in input_list:迭代input_list,将out_exp传入out_exp_res表达式中;
if out_exp == 2:判断根据条件可以过滤哪些值。


##### 先来讲讲—range函数list序列迭代对象


* Python3 range() 函数返回的是一个可迭代对象(类型是对象),而不是列表类型, 所以打印的时候不会打印列表。
* Python3 list() 函数是对象迭代器,可以把range()返回的可迭代对象转为一个列表,返回的变量类型为列表。


①range 语法:  
 range(stop)  
 range(start, stop[, step])  
 ②参数说明:  
   start: 计数从 start 开始。默认是从 0 开始。例如range(5)等价于range(0, 5);  
   end: 计数到 end 结束,但不包括 end。例如:range(0, 5) 是[0, 1, 2, 3, 4]没有5  
   step:步长,默认为1。例如:range(0, 5) 等价于 range(0, 5, 1)



-*- coding: utf-8 -*-

“”"
__author__ = 小小明-代码实体
“”"

coding=utf-8

print(list(range(10))) # 产生一个0-9的序列
print(list(range(3, 10))) # 产生一个3-9的序列
print(list(range(0, 10, 3))) # 产生从0开始,按3递增,最大值为9的序列
print(list(range(10, -1, -1))) # 产生从10开始,最小值为0的递减序列


![在这里插入图片描述](https://img-blog.csdnimg.cn/b9e6213c6976467c8835365b66823889.png)


##### 第一个:基本使用


* 我先来实战讲解一下,然后下面出两道很简单的小题目:



#coding=utf-8

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

#还可以使用两层循环,可以生成全排列:
print([m + n for m in ‘ABC’ for n in ‘XYZ’])
print([str(x)+str(y) for x in range(1,6) for y in range(11,16)])

#for循环其实可以同时使用两个甚至多个变量,比如dict的items()可以同时迭代key和value:
d = {‘x’: ‘A’, ‘y’: ‘B’, ‘z’: ‘C’ }
print([k + ‘=’ + v for k, v in d.items()])


![在这里插入图片描述](https://img-blog.csdnimg.cn/1852599e6c4a4e6aa1fd152d5e24bf51.png)


###### 第一题:创建一个包含从1到10的平方的列表。


**惯性思维——常规方法解决:**



list_end = []
for x in range(10):
list_end.append(x**2)
print(list_end)


**借由列表推导式——一行代码解决:**



list_end1 = [x**2 for x in range(10)]
print(list_end1)


二者输出都为:  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20210622215806463.png)


###### 第二题:输出30以内能够整除3的整数。


**传统方法实现:**



nums = []
for x in range(30):
if x % 3 == 0:
nums.append(x)
print(nums)


**使用列表推导式一行代码解决:**



nums1 = [x for x in range(30) if x % 3 == 0]
print(nums1)


二者输出都为:  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20210622220024945.png)


##### 第二个:升级版使用——使用列表生成式的同时使用函数处理


**需求:首先获取30以内能够整除3的整数,然后一次输出所获得整数的平方。**



def squared(x):
return x**2

end = [squared(x) for x in range(30) if x % 3 == 0]
print(end)


![在这里插入图片描述](https://img-blog.csdnimg.cn/2021062222033980.png)


##### 第三个:高级版使用——删选列表中特定元素的高级操作


在python程序中,有时候筛选列表中的某些特定元素时,筛选标准无法简单的表示在列表推导式或生成器表达式中,例如当筛选过程涉及异常处理或者其他一些复杂的细节时。此时可以**考虑将处理筛选功能的代码放到单独的功能函数中,然后使用内建的filter()函数进行处理。**


需求:筛选指定列表中的所有整数元素!



values = [‘1’, ‘2’, ‘-3’, ‘-’, ‘4’, ‘N/A’, ‘5’]
def is_int(val):
try:
x = int(val)
return True
except ValueError:
return False

注意:因为使用函数filter()创建了一个迭代器,所以想要得到一个列表形式的结果,必须在filter()前面加上list()函数。

isvals = list(filter(is_int, values))
print(isvals)


![在这里插入图片描述](https://img-blog.csdnimg.cn/20210622221326308.png)


#### 二、列表生成器


* 通过列表生成式,我们可以直接创建一个列表。但是,受到内存限制,列表容量肯定是有限的。而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费了。
* 所以,如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢?这样就不必创建完整的list,从而节省大量的空间。在Python中,这种一边循环一边计算的机制,称为生成器:generator。
* 只要把一个列表生成式的[]改成(),就创建了一个generator:  
 `g = (x * x for x in range(10))`
* generator保存的是算法,每次调用next(g),就计算出g的下一个元素的值,直到计算到最后一个元素,没有更多的元素时,抛出StopIteration的错误。



-*- coding: utf-8 -*-

“”"
__author__ = 小小明-代码实体
“”"
for x in (x * x for x in range(1, 11)):
print(x, end=" “)
print()
for x in (x * x for x in range(1, 11) if x % 2 == 0):
print(x, end=” ")


![在这里插入图片描述](https://img-blog.csdnimg.cn/6af6b0fa02954b9284131808c04282a1.png)


#### 三、函数列表生成器


* 如果推算的算法比较复杂,用类似列表生成式的for循环无法实现的时候,还可以用函数来实现。  
 比如,著名的斐波拉契数列(Fibonacci),除第一个和第二个数外,任意一个数都可由前两个数相加得到:  
 1, 1, 2, 3, 5, 8, 13, 21, 34, …
* 斐波拉契数列用列表生成式写不出来,但是,用函数把它打印出来却很容易:



-*- coding: utf-8 -*-

“”"
__author__ = 小小明-代码实体
“”"
def fib(max):
n, a, b = 0, 0, 1
while n < max:
print(b)
a, b = b, a + b
n = n + 1


* 上面的函数可以输出斐波那契数列的前N个数:



fib(6)
1
1
2
3
5
8


* 仔细观察,可以看出,fib函数实际上是定义了斐波拉契数列的推算规则,可以从第一个元素开始,推算出后续任意的元素,这种逻辑其实非常类似generator。
* 也就是说,上面的函数和generator仅一步之遥。要把fib函数变成generator,只需要把print(b)改为yield b就可以了:



-*- coding: utf-8 -*-

“”"
__author__ = 小小明-代码实体
“”"
def fib(max):
n, a, b = 0, 0, 1
while n < max:
yield b
a, b = b, a + b
n = n + 1


* 这就是定义generator的另一种方法。如果一个函数定义中包含yield关键字,那么这个函数就不再是一个普通函数,而是一个generator:



fib(6)
<generator object fib at 0x104feaaa0>


* 这里,最难理解的就是generator和函数的执行流程不一样。函数是顺序执行,遇到return语句或者最后一行函数语句就返回。而变成generator的函数,在每次调用next()的时候执行,遇到yield语句返回,再次执行时从上次返回的yield语句处继续执行。
* 举个简单的例子,定义一个generator,依次返回数字1,3,5:



-*- coding: utf-8 -*-

“”"
__author__ = 小小明-代码实体
“”"
def odd():
print(‘step 1’)
yield 1
print(‘step 2’)
yield(3)
print(‘step 3’)
yield(5)


* 调用该generator时,首先要生成一个generator对象,然后用next()函数不断获得下一个返回值:



o = odd()
next(o)
step 1
1
next(o)
step 2
3
next(o)
step 3
5
next(o)
Traceback (most recent call last):
File “”, line 1, in
StopIteration


* 可以看到,odd不是普通函数,而是generator,在执行过程中,遇到yield就中断,下次又继续执行。执行3次yield后,已经没有yield可以执行了,所以,第4次调用next()就抛出StopIteration异常。
* 可以for循环迭代generator:



for i in odd():
print(i)


![在这里插入图片描述](https://img-blog.csdnimg.cn/48b6badfef304fc388485dd8861026a3.png)


* 回到fib的例子,我们在循环过程中不断调用yield,就会不断中断。当然要给循环设置一个条件来退出循环,不然就会产生一个无限数列出来。
* 同样的,把函数改成generator后,我们基本上从来不会用next()来调用它,而是直接使用for循环来迭代:



for n in fib(6):
print(n)


* generator是在for循环的过程中不断计算出下一个元素,并在适当的条件结束for循环。对于函数改成的generator来说,遇到return语句或者执行到函数体最后一行语句,就是结束generator的指令,for循环随之结束。


### (5)删除列表中的重复元素并保持顺序不变


#### 第一个版本:


**需求:删除列表中重复出现的元素,并且保持剩下元素的显示顺序不变。如果序列中保存的元素是[可散列的(hashable)](https://bbs.csdn.net/topics/618545628),那么此功能可以使用集合和生成器实现。**



知识点补给站:
如果一个对象是可散列的,那么在它的生存期内必须是不可变的,这需要有一个__hash__()方法。在python程序中,
整数,浮点数,字符串和元组都是不可变的。


上代码:



def fun(items):
seen = set()
for item in items:
if item not in seen:
yield item
seen.add(item)

if name == ‘__main__’:
a = [5, 3, 3, 8, 6, 5, 9]
print(a)
print(list(fun(a)))


![在这里插入图片描述](https://img-blog.csdnimg.cn/20210622221736874.png)


#### 第二个版本:


**上述代码有个缺陷——只有当序列中的元素是可散列的时候才能实现功能。如果想在不可散列的对象序列中实现此功能,该如何实现呢?**  
 上代码:



def fun(items, key=None):
seen = set()
for item in items:
val = item if key is None else key(item)
if val not in seen:
yield item
seen.add(val)

if name == ‘__main__’:
a = [
{‘x’ :2, ‘y’:3},
{‘x’ :1, ‘y’:4},
{‘x’ :2, ‘y’:3},
{‘x’ :2, ‘y’:3},
{‘x’ :10, ‘y’:15}
]
print(a)
print(list(fun(a, key=lambda a: (a[‘x’], a[‘y’]))))


**注意:上述代码中函数fun()中的参数key的功能是将序列中的元素转换为可散列的类型,这样做的目的是检测重复选项。**


![在这里插入图片描述](https://img-blog.csdnimg.cn/20210622222631269.png)







![img](https://img-blog.csdnimg.cn/img_convert/994e517fe06d69d12febc15e4beb862c.png)
![img](https://img-blog.csdnimg.cn/img_convert/1fcb7bd7faf2bd5a9b799f778572f773.png)
![img](https://img-blog.csdnimg.cn/img_convert/ab1ee8f04cfea8cb8502e3ca6c8ea639.png)

**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上大数据知识点,真正体系化!**

**由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新**

**[需要这份系统化资料的朋友,可以戳这里获取](https://bbs.csdn.net/topics/618545628)**

'y':4},
        {'x' :2, 'y':3},
        {'x' :2, 'y':3},
        {'x' :10, 'y':15}
    ]
    print(a)
    print(list(fun(a, key=lambda a: (a['x'], a['y']))))

注意:上述代码中函数fun()中的参数key的功能是将序列中的元素转换为可散列的类型,这样做的目的是检测重复选项。

在这里插入图片描述

[外链图片转存中…(img-6Vtj7jU2-1715104093742)]
[外链图片转存中…(img-QyadnKsH-1715104093742)]
[外链图片转存中…(img-yczQqaBl-1715104093742)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上大数据知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

需要这份系统化资料的朋友,可以戳这里获取

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值