Python 面试小笔记

python基础知识:

0.简述python:
python是一种解释型语言,和C语言等语言不同的是,python运行前不需要编译,使用变量时不需要事先声明变量的类型。python编写快,但运行比较慢。

python模块是包含python代码的.py文件,前人写好的可以调用的模块。
常见的python内置模块:sys, datetimemathrandomos

Python解释器:
程序代码是用编程语言编写的,计算机CPU只能听懂机器指令。我们需要一个翻译,把Python语言翻译成 计算机CPU能听懂的机器指令。
这个翻译就是 Python解释器

运行Python程序,就是运行Python解释器,让解释器去读取我们写好的Python代码文件,并且把Python代码翻译成机器指令给 CPU 去执行。

Python语言中,所有的数据都被称之为对象,例如hello就是字符类型的对象,233就是整型对象。

在Python程序运行的时候,这些对象其实就是内存中的一段数据 。
Python语言中对象的名字, 称之为变量名,有时也简称变量
所以Python中的变量,就是对象的名字
使用的方式:变量名 = 数据对象

python2和python3的区别?

  1. py2中range(1, 5)返回列表,py3中返回迭代器
  2. py2使用ascii编码,py3中使用utf-8
  3. py2中使用中文要引入coding声明
  4. py3中print要加小括号,py2中可以小括号也可以使用一个空格
  5. py2中使用raw_input(),py3使用input()

1.大数据文件读取:

  1. 用生成器: generator
  2. 用迭代器:for line in file

2.迭代器:
是访问集合元素的一种方式。迭代器是一个可以记住遍历的位置的对象。迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。
迭代器有两个基本的方法:iter() 创建一个迭代器和 next()访问元素。
字符串string,列表list或元组tuple对象都可用于创建迭代器

list=[1,2,3,4]
it = iter(list)    # 创建迭代器对象
print (next(it))   # 输出迭代器的下一个元素

3.生成器:

在 Python 中,使用了 yield 的函数被称为生成器(generator)。跟普通函数不同的是,生成器是一个返回迭代器的函数,只能用于迭代操作,更简单点理解生成器就是一个迭代器。在调用生成器运行的过程中,每次遇到 yield 时函数会暂停并保存当前所有的运行信息,返回 yield 的值, 并在下一次执行 next() 方法时从当前位置继续运行。调用一个生成器函数,返回的是一个迭代器对象。

注: 生成器和迭代器的区别:生成器能做到迭代器能做的所有事,生成器更简便更高效。

X= (i for i in range(10))
X是 generator类型

4.装饰器: @函数名

# python会自动执行 func(xxx),把func作为参数执行装饰器的函数
# 执行完再把结果赋值给 xxx
# 相当于执行xxx = func(xxx)
@func
def xxx:
	pass

装饰器本质上是一个Python函数,它可以让其他函数在不需要做任何代码变动的前提下增加额外功能,对原函数进行包装,返回另一个函数。装饰器的返回值也是一个函数对象。它经常用于有切面需求的场景:
在装饰器里面定义的装饰器函数的参数最好为argskwargs,这样对于任意的目标函数都可以。

  1. 引入日志
  2. 函数执行时间统计
  3. 执行函数前预备处理
  4. 执行函数后清理功能
  5. 权限校验
  6. 缓存

一句话解释什么样的语言能够用装饰器?
函数可以作为参数传递的语言,可以使用装饰器

5.GIL全局解释器锁:
是一个互斥锁,它防止多个本机线程同时执行Python字节码。

  1. GIL 是python的全局解释器锁,同一进程中假如有多个线程运行,一个线程在运行python程序的时候会霸占python解释器(加了一把锁即GIL),使该进程内的其他线程无法运行,等该线程运行完后其他线程才能运行。如果线程运行过程中遇到耗时操作,则解释器锁解开,使其他线程运行。所以在多线程中,线程的运行仍是有先后顺序的,并不是同时进行。
  2. 多进程中因为每个进程都能被系统分配资源,相当于每个进程有了一个python解释器,所以多进程可以实现多个进程的同时运行,缺点是进程系统资源开销大

6.find和grep的区别

  • grep是通过文件找内容
  • find 是通过内容找文件

7.如何提高python的运行效率?

使用外部包(cython等),优化循环,避免在循环中访问变量的属性

8.yield()的作用:
yield 的作用就是把一个函数变成一个 generator,带有 yield 的函数不再是一个普通函数,Python解释器会将其视为一个generator,函数记住它上一次返回时在函数体的位置。

9.python如何进行内存管理?
由python私有堆进行空间管理,程序员无法访问私有堆。
python不用事先声明变量的类型再进行赋值,是一种动态语言,python采用了类似于windows内核对象一样的方式来对内存进行管理,每一个对象都有一个对应的计数,系统会自动维护并定时扫描,当变量绑定一个对象是计数就是1,当计数为0时,内存就会回收。
内存池机制是金字塔形,最底下是操作系统控制,上面一点是c的malloc和free。

10.数组、链表、队列、堆栈
数组和链表是数据存储的方式的概念,数组在连续的空间中存储,链表可以在非连续的空间中存储。

队列和堆栈是描述数据存取方式的方式,队列是先进先出,堆栈是后进先出。

11.python深拷贝和浅拷贝的区别
深拷贝:copy.deepcopy()
浅拷贝:copy.copy()
首先深拷贝和浅拷贝都是对象的拷贝,都会生成一个看起来相同的对象,他们本质的区别是拷贝出来的对象的地址是否和原对象一样,也就是地址的复制还是值的复制的区别。

当对象是不可变数据类型是,深浅拷贝都和赋值=一样

12.python如何实现单例模式?请写出两种实现方式?
单例模式(Singleton Pattern)是一种常用的软件设计模式,该模式的主要目的是确保某一个类只有一个实例存在

第一种方法:使用装饰器

def singleton(cls):
	instances = {}
	def wrapper(*args, **kwargs):
		if cls not in instances:
			instances[cls] = cls(*args, **kwargs)
		return instances[cls]
	return wrapper

@singleton
class Foo(object):
	pass
foo1 = Foo()
foo2 = Foo()
print(foo1 is foo2) # True

第二种方法:使用基类
New 是真正创建实例对象的方法,所以重写基类的new 方法,以此保证创建对象的时候只生成一个实例

class Singleton(object):

def __new__(cls, *args, **kwargs):
	if not hasattr(cls, '_instance'):
		cls._instance = super(Singleton, cls).__new__(cls, *args, **kwargs)
	return cls._instance
	
class Foo(Singleton):
	pass
foo1 = Foo()
foo2 = Foo()
print(foo1 is foo2) # True

13.Python的魔法方法
魔法方法就是可以给你的类增加魔力的特殊方法,如果你的对象实现(重载)了这些方法中的某一个,那么这个方法就会在特殊的情况下被Python所调用,你可以定义自己想要的行为,而这一切都是自动发生的,它们经常是两个下划线包围来命名的(比如 __init___ , __len__ ),Python的魔法方法是非常强大的所以了解其使用方法也变得尤为重要!

__init__ 对象初始化方法,当一个实例被创建的时候初始化的方法,但是它并不是实例化调用的第一个方法。__init__ 第一个参数永远是self,就是__new__ 返回的实例,__init__ 不需要返回值。

__new__ 才是实例化对象调用的第一个方法,至少有一个参数cls,代表当前类。它只取下cls参数,并把其他参数传给 __init_____new__ 必须有返回值。创建对象执行的方法,单例模式会用到。

___new__ 很少使用,但是也有它适合的场景,尤其是当类继承自一个像元祖或者字符串这样不经常改变的类型的时候。

self:
而Python中就规定好了,函数的第一个参数,就必须是实例对象本身,并且建议,约定俗成,把其名字写为self

class Person(object):	#类的定义
    pass
student = Person()    # 创建类的实例化

类中定义的函数:

1、第一个参数永远是 self ,并且调用时不用传递该参数

2、在类中函数相互调用要加 self

c = self.add()+self.square()	#add()square()都是定义在类中的函数

14.谈谈你对面向对象的理解?
面向对象是相当于面向过程而言的,面向过程语言是一种基于功能分析的,以算法为中心的程序设计方法。
而面向对象是一种基于结构分析的,以数据为中心的程序设计思想。在面向对象语言中有一个很重要的东西,叫做类。面向对象有三大特性:封装继承多态

15.面向对象中怎么实现只读属性?
将对象私有化,通过共有方法提供一个读取数据的接口

class person:
	def __init__(self, x):
		self.__age = 10
	def age(self):
		return self.__age
t = person(22)
# t.__age =100
print(t.age())

最好的方法:

class MyCls(object):
	__weight = 50
	
	@property
	def weight(self):
		return self.__weight

16.简述Python里面search和match的区别
match()函数只检测字符串开头位置是否匹配,匹配成功才会返回结果,否则返回None;
search()函数会在整个字符串内查找模式匹配,只到找到第一个匹配然后返回一个包含匹配信息的对象,该对象可以通过调用group()方法得到匹配的字符串,如果字符串没有匹配,则返回None。

17.python引用计数机制:
当一个变量保存了对象的引用,此对象的引用计数+1
当del删除变量指向的对象时,次对象的引用计数-1,变为0时会真正将对象删除

18.python传参数是传值还是传指针?
python中函数参数是引用传递(注意不是值传递)。对于不可变类型(int, float,str, tuple),因变量不能修改,所以运算不会影响到变量自身;
而对于可变类型(list,dict),函数体运算可能会更改传入的参数变量;


web方面:

1.Ajax是什么?怎么实现
Ajax是异步的JavaScript和xml,可以刷新局部网页数据而不用重新加载整个网页。

2.cookie 和session的区别:

  1. cookie在用户的浏览器上,session在服务器上
  2. cookie没有session安全
  3. session过多可能会影响服务器性能
  4. 重要信息用session存,其他信息用cookie

爬虫方面:

1.scrapy和scrapy-redis的区别
scrapy是一个python爬虫框架,效率很高,定制性也强,但是不支持分布式
scrapy-redis是基于redis数据库,在scrapy之上的组件,可以让scrapy实现分布式策略。

为什么选择redis数据库?
redis指出主从同步,而且所有数据都缓储在内存中,基于redis的分布式爬虫对请求和数据的高频读取效率非常高。

2.scrapy框架运行机制:
Scrapy引擎发送请求,之后调度器(Scheduler)把初始URL交给下载器(Downloader),然后下载器向服务器发送服务请求,得到响应后将下载的网页内容交与spider来处理,尔后spider会对网页进行详细的解析。
蜘蛛分析的结果有两种:
一种是得到新的URL,之后再次请求调度器,开始进行新一轮的爬取,不断的重复上述过程;
另一种是得到所需的数据,之后会转交给项目管道(Pipeline)继续处理。项目管道负责数据的清洗、验证、过滤、去重和存储等后期处理,最后由Pipeline输出到文件中,或者存入数据库等。

3.爬虫多线程好还是多进程好:
IO密集型操作时候,多线程可提高效率,线程a等待时自动切换到线程b,节约了cpu资源,提高了效率。
实际情况要具体分析。

实现小功能:

1.输出九九乘法表

for i in range(1, 10):
    for j in range(1, i+1):
        print(f"{i} * {j} = {i * j}", end = '\t')
    print()


# for x in range(1, 10):
#     for y in range(1, x+1):
#         print( "%d * %d = %2d\t" %(y, x, x*y), end="")
#     print("")

2.输出成绩

while True:
    x = int(input(">>>:"))
    score = 'A' if x >= 90 else 'B' if 60 <= x < 90 else 'C'
    print(score)

3.求出列表中是偶数并且位置也是偶数并构造新列表
列表递推式:[表达式 for 变量 in 列表] 或者 [表达式 for 变量 in 列表 if 条件]

def num_list(num):
return [i for i in num if i %2 ==0 and num.index(i)%2==0]

num = [0,1,2,3,4,5,6,7,8,9,10]
result = num_list(num)
print(result)

列表表达式改成生成器:

#[]改为()即可
a = (i for i in range(3))	

4.冒泡排序

# 从小到大
def bubbleSort(arr):
    length = len(arr)

    for passnum in range(length-1,0,-1):
        for i in range(passnum):
            if arr[i] > arr[i+1]:
                arr[i], arr[i+1]= arr[i+1], arr[i]

    return arr

arr = [23, 41, 25, 54, 18, 14]
print(bubbleSort(arr))


常见面试题:

1.删除字典的键del dict[key]

2.字典的合并 dict1.update(dict2)

3.列表去重:先转化为集合,再转化为列表L2=set(L2)L2 = list(L2)

4.函数里面的argskwargs是什么意思?
args表示可以传一个可变数量的参数列表
kwargs表示可以传一个不定长度的键值对

5.python生成随机整数,随机小数,0-1之间的随机数方法
随机整数 random.randint(a,b)
随机小数 random.random()
生成5个随机小数:numpy库,利用np.random.randn(5)
0-1之间的随机数 random.random()
打乱一个排好序的list:random.shuffle()

6.可变数据类型和不可变数据类型
可变数据类型
允许变量的值发生变化,对于相同的值的不同对象,在内存中则会存在不同的对象。还是同一个地址,值变了。
例如:listdict

不可变数据类型
不允许变量的值发生变化,如果改变了变量的值,相当于是开辟了一个新的地址,而对于相同的值的对象,在内存中则只有一个对象
例如:int、float、tuple

a = 3
b = 3

print(id(a))    #这两个打印出来的结果是一样的
print(id(b))

7.对字符串先去重再排序
转化成集合set去重,再转化为列表s,使用s.sort(reverse=False) 得到排序的列表,使用"".join(s)得到去重排序后的字符串
注意:s.sort没有返回值,s = s.sort()是错误的

8、python中断言方法举例

assert()方法,断言成功,则程序继续执行,断言失败,则程序报错

a = 5
assert(a > 1)
print("断言成功,程序继续执行")

9.根据值对字典进行排序

dict = {‘candy’:21, ‘mandy’:27, ‘ciddy’:17, ‘kitty’:24, ‘tom’:32}
res = sorted(dict.items(), key=lambda d:d[1], reverse=False)
print(res)

10.统计字符串中每个字符出现的次数
直接使用collection里面的Counter(变量名)

11.将二维列表转化为一维列表

from tkinter import _flatten

a = [[1,2],[3,4]]
print(list(_flatten(a)))

12.常用的正则表达式

  1. re.compile的作用:将正则表达式编译成一个对象,加快速度并重复使用
  2. 正则匹配中文pattern = re.compile(r’[\u4e00-\u9fa5]+’)

13. 简述 进程、线程、协程
线程是并发,进程是并行;
进程之间互相独立,是系统分配资源的最小单位,同一个进程中的所有线程共享资源。

进程:
一个运行的程序(代码)就是一个进程,没有运行的代码叫程序,进程是系统资源分配的最小单位,进程拥有自己独立的内存空间,所以进程间数据不共享,开销大。

线程:
调度执行的最小单位,也叫执行路径,不能独立存在,依赖进程存在一个进程至少有一个线程,叫主线程,而多个线程共享内存(数据共享,共享全局变量),从而极大地提高了程序的运行效率。

协程:
是一种用户态的轻量级线程,协程的调度完全由用户控制。协程拥有自己的寄存器上下文和栈。
协程调度时,将寄存器上下文和栈保存到其他地方,在切回来的时候,恢复先前保存的寄存器上下文和
栈,直接操中栈则基本没有内核切换的开销,可以不加锁的访问全局变量,所以上下文的切换非常快。

14.IO密集型和CPU密集型区别?
IO密集型: 系统运行,大部分的状况是CPU在等 I/O(硬盘/内存)的读/写
CPU密集型: 大部分时间用来做计算,逻辑判断等CPU动作的程序称之CPU密集型。

15.python中多进程与多线程的使用场景
多进程适合在CPU密集操作(cpu操作指令比较多,如位多的的浮点运算)。
多线程适合在IO密性型操作(读写数据操作比多的的,比如爬虫)

18. 什么是并发和并行?
并发(Concurrent)
在操作系统中,是指一个时间段中有几个程序都处于已启动运行到运行完毕之间,且这几个程序都是在同一个处理机上运行。

并行(Parallel)
当系统有一个以上CPU时,当一个CPU执行一个进程时,另一个CPU可以执行另一个进程,两个进程互不抢占CPU资源,可以同时进行,这种方式我们称之为并行(Parallel)。

19.lamuda函数实现两数相乘

sum = lamuda a, b:a*b
print(sum(2, 3))

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

d={"name":"zs","age":18,"city":"深圳","tel":"1362626627"}
# d.item()的结果是字典的键值对元组 i[0]是按key排序 i[1]是按value排序 用lambda函数排序
list = sorted(d.items(), key=lambda i:i[0], reverse= False)

21.数组和列表的区别:
数组只包含单个数据类型元素,列表可以包含任意数据类型的元素

22.help()和dir()函数:
都是python内置了很多内置函数,在命令行用
help():了解模块、类型、对象、方法、属性的详细信息,显示文档字符串

dir():用来查询一个类或者对象所有属性
print dir( 'a') 的输出?
输出字符串’a’的内建方法

23.反转字符串:

print("str1"[::-1])

24.split()方法
split() 通过指定分隔符对字符串进行切片

x = txt.split("#", 1)	//按照#进行切片,分割1次

25.下面代码的输出结果将是什么?

list = ['a','b','c','d','e']
print(list[10:])

#结果为[]

25.写一个列表生成式,产生一个公差为11的等差数列

print([x*11 for x in range(10)])

26.is和==有什么区别?
is:比较的是两个对象的id值是否相等,也就是比较俩对象是否为同一个实例对象。是否指向同一个内
存地址。
== : 比较的两个对象的内容/是否相等,默认会调用对象的eq()方法

27.使用Python内置的filter()方法来过滤?

list(filter(lambda x: x % 2 == 0, range(10)))

28.为什么函数名字可以当做参数用?
Python中一切皆对象,函数名是函数在内存中的空间,也是一个对象

29.Python中pass语句的作用是什么?
在编写代码时只写框架思路,具体实现还未编写就可以用pass进行占位,是程序不报错,不会进行任何
操作。

30.什么是lambda函数? 有什么好处?
lambda 函数是一个可以接收任意多个参数(包括可选参数)并且返回单个表达式值的函数。
lambda函数是匿名函数,使用lambda函数能创建小型匿名函数,这种函数得名于省略了用def声明函数的标准步骤

  1. lambda函数比较轻便,即用即丢,很适合需要完成一项功能,但是此功能只在此一处使用,连名字都很随意的情况下
  2. 匿名函数,一般用来给filter,map这样的函数式编程服务
  3. 作为回调函数,传递给某些应用,比如消息处理

31.解释以下什么是闭包?
在函数内部再定义一个函数,并且这个函数用到了外边函数的变量,那么将这个函数以及用到的一些变
量称之为闭包。

32.map()、reduce()函数使用
map(): 是 python 内置的高阶函数,它接收一个函数 f 和一个 list,并通过把函数 f 依次作用在 list 的每个元素上,得到一个新的object并返回(python3 返回一个迭代对象)

list = [1, 2, 3, 4, 5]

def fn(x):
    return x ** 2	#平方

res = map(fn, list)
res = [i for i in res if i > 10]	#列表递推式得到大于10的数组成的列表
print(res)

map()的主要作用就是:并行
map函数和zip函数都是用来进行并行运算,迭代等。
在多进程编程中,Pool池的用法中一种就是利用map函数开启多进程,可以大大提高程序的效率。

reduce() 的使用方法形如reduce(function, iterable[, initializer]),它的形式和map()函数一样。不过参数function必须有两个参数,initializer是可选的。
:在Python3中reduce不再是内置函数,而是集成到了functools中,需要导入

33.统计字符串中字符出现次数

from collections import Counter

a = "sdacfe scs as;sdacssdljo"
res = Counter(a)
print(res)

34.filter()方法求出列表中的奇数并构建新列表:
filter()用于过滤序列,过滤掉不符合指定函数的元素

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

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

new_list = filter(f, a)	#第一个参数为函数,第二个参数为列表
new_list = [i for i in new_list]
print(new_list)    #[1, 3, 5, 7, 9]


#也可以直接用列表递推式
new_list = [i for i in a if i%2 == 1]
print(new_list)

35.打印时间戳:

import datetime

a = str(datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")) + ' 星期: ' + str(datetime.datetime.now().isoweekday())
print(a)    #2021-01-22 14:25:19 星期: 5

36.自定义异常:
用raise()自定义抛出异常:

def fn():
    try:
        for i in range(5):
            if i > 2:
                raise Exception("数字大于2了")
    except Exception as ret:
    	print(ret)  #数字大于2fn()

try…except…else:没有捕获异常,执行else
try…except…finally:不管有没有捕获异常,都执行finall

37.zip()函数:
zip()函数可以将1个或多个序列(可迭代对象作为参数),返回一个元组列表,能将并排的元素配对。(以最短长度为准)

a = ['x', 'y', 'z']
b = [1, 2]

res = [i for i in zip(a, b)]
print(res)  #[('x', 1), ('y', 2)]

38.保留两位小数

a = 10
b = 3

ans = a/ b
print("%.2f"%ans)
print(round(ans, 2))

39.sort()和sorted()的区别:
sort()在原先list上修改,无返回值
sorted()有返回值

40.字典和json字符串互相转化方法:
josn.dumps():字典转json字符串
json.loads():json转字典

41.捕获异常

 try:
        miles = input('请输入英里数:')
        km = int(miles) * 1.609344
        print(f'等于{km}公里')
    except ValueError:
        print('你输入了非数字字符')

try下面缩进的3行代码可以看成是保护区中的代码。
如果执行保护区中代码时,出现异常,解释器会结束保护区中后续代码的执行,并检查这个异常的类型是否匹配后面的except 语句中声明的类型。

如果匹配上,解释器知道程序对此种异常是预料到的,并且有对应的处理方案,也就是匹配的except下面缩进的代码。解释器就执行匹配的except下面缩进的代码,不会因此中止程序。

42.获取异常对象
我们使用except 语句匹配异常类型的时候, 可以使用as关键字,后面加一个变量名,如下所示:

try:
    100/0
except ZeroDivisionError as e:
    print (f'异常对象信息:{e}')

这样,运行代码的时候,当try中的语句产生异常对象时,就会 把产生的异常对象赋值给as后的变量。

上面的代码,运行输出

异常对象信息:division by zero

产生的异常对象赋值给了变量 e。这样我们就可以在后续的代码中得到产生的异常对象的信息。

43.匹配所有异常
如果我们在写一段代码的时候,不知道这段代码会抛出什么样的异常,并且我们不希望程序因为异常而中止。

这时我们可以匹配所有类型的异常,这样任何类型的异常发生都不会终止程序了。 如下:

try:
    100/0
except Exception as e:
    print('未知异常:', e)

因为所有的异常都是 Exception 的子类。 所以 Exception能匹配所有类型的异常。

还有一种更简洁的写法,也可以匹配所有类型的异常,如下所示

try:
    100/0
except:
    print('未知异常:')

except 后面 没有写异常的类型,也表示匹配所有的异常。

异常类型都是 继承自Exception的类,表示各种类型的错误。

我们也可以自己定义异常,比如我们写一个用户注册的函数, 要求用户输入的电话号码只能是中国的电话号码,并且电话号码中不能有非数字字符。

可以定义下面这两种异常类型:

# 异常对象,代表电话号码有非法字符
class InvalidCharError(Exception):
    pass

# 异常对象,代表电话号码非中国号码
class NotChinaTelError(Exception):
    pass

定义了上面的异常,当用户输入电话号码时,出现相应错误的时候,我们就可以使用raise 关键字来抛出对应的自定义异常


正则表达式:

1.过滤掉英文和数字

import re

a = "2021 get better 小陈 23 杭州"
list= a.split(" ")
print(list) #['2021', 'get', 'better', '小陈', '23', '杭州']
res = re.findall('\d+|[a-zA-Z]+', a)

for i in res:
    if i in list:
        list.remove(i)

new_list = " ".join(list)
print(list) #['小陈', '杭州']
print(new_list) #小陈 杭州

2.re.comple作用:
将正则表达式编译成一个对象,加快速度并重复使用

3.(.*)和(.*?)的区别?
(.*):贪婪匹配,尽可能多
(.*?):非贪婪匹配,尽可能少

4.re.sub() 将98换成100:

a = "小陈 98分"
res = re.sub(r"\d+", 100, a)

5.请写出匹配ip的Python正则表达式

6.正则表达式匹配第一个URL
findall结果不用加group(),search()需要加group()提取

import re

s = '<img data-original = "https://rpic.douyucdn.cn/appCovers/2016/11/13/1213973_201611131917_small.jpg" scr="https://rpic.douyucdn.cn/appCovers/2016/11/13/1213973_201611131917_small.jpg" style = "display:inline"'

res = re.findall(r"https://.*?\.jpg", s)[0]
print(res)	

res = re.search(r"https://.*?\.jpg", s)
print(res.group())
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值