Python 小知识

到底什么是 Python ?你可以在回答中与其他技术进行对比


下面是一些关键点:
Python 是一种解释型语言,它的源代码可以直接运行。这就是说,与 C 语言和 C 的衍生语言不同,Python 代码在
运行之前不需要编译。其他解释型语言还包括 PHP 和 Ruby。

Python是如何被解释的?      Python解释器会将源代码转换成中间语言,之后再翻译成机器码再执行。
Python 是动态类型语言,指的是你在声明变量时,不需要说明变量的类型。你可以直
接编写类似 x=111 和 x="I'm a string"这样的代码,程序不会报错。
Python 非常适合面向对象的编程(OOP),因为它支持通过组合(composition)与继
承(inheritance)的方式定义类(class)。
Python 中没有访问说明符( access specifier ,类似 C++ 中的 public 和 private ),
这么设计的依据是 “ 大家都是成年人了 ” 。
在 Python 语言中,函数是第一类对象(first-class objects)。这指的是它们可以被指定
给变量,函数既能返回函数类型,也可以接受函数作为输入。类(class)也是第一类对
象。(一切皆对象)

Python 代码编写快,但是运行速度比编译语言通常要慢。好在 Python 允许加入基于 C
语言编写的扩展,因此我们能够优化代码,消除瓶颈,这点通常是可以实现的。
numpy 就是一个很好地例子,它的运行速度真的非常快,因为很多算术运算其实并不是
通过 Python 实现的。
 Python 用途非常广泛——网络应用,自动化,科学建模,大数据应用,等等。它也常
被用作“胶水语言”,帮助其他语言和组件改善运行状况。
 Python 让困难的事情变得容易,因此程序员可以专注于算法和数据结构的设计,而不
用处理底层的细节。
为什么提这个问题:如果你应聘的是一个
Python
开发岗位,你就应该知道这是门什
么样的语言,以及它为什么这么酷。以及它哪里不好。

PEP8编码规范

 

 

进程与线程

进程是程序执行的最小单元,每个进程都有自己独立的内存空间,而线程是进程的一个实体,是系统调用调用的一个基本单位。

举个栗子吧:

我们启动一个app 这就创建了一个进程,这个app里可能有语音播放、搜索等功能,这些是进程里不同的线程。

注意:线程是轻量级的,他没有独立的空间地址(内存空间),因为他是由进程创建的,寄存在进程的内存地址中。一个进程会包含多个线程

 

手写二分查找

def binary_search(list,item):
    low = 0 #用于跟踪其要在列表中查找到部分
    high = len(list)-1
    guess = list[mid]
    while low <= high:
        mid = (low+high)//2 #取整
        if guess == item: #找到了元素
            return mid
        if guess > item: #猜的数值大了
            high = mid-1
        else:                  #猜的数值小了
            low = mid+1
    return None #没有指定元素

if __name__== '__main__':
    my_list = [1,3,5,7,9,11,13,15]
    print(binary_search(my_list,5))
    print(binary_search(my_list,-1))

 

is 和 ==

==是python标准操作符中的比较操作符,用来比较判断两个对象的value(值)是否相等

is这个运算符比较判断的是对象间的唯一身份标识,也就是id是否相同

多赋值

a = b = c = 0

元组赋值

a, b, c = 1, 2, 3

同步赋值

a, b = 1, 2  

a, b = a+b, a     (a=a+b,b=a同时进行,运算时都利用原始值)

列表元素顺序反向

list = [-1::-1]

format函数

基本介绍:一种格式化字符串的函数 ,它增强了字符串格式化的功能。
基本语法是通过 {} 和 : 来代替以前的 % 。

format 函数可以接受不限个参数,位置可以不按顺序。

print("网站名:{name}, 地址 {url}".format(name="菜鸟教程", url="www.runoob.com"))

# 通过字典设置参数 site = {"name": "菜鸟教程", "url": "www.runoob.com"}

print("网站名:{name}, 地址 {url}".format(**site))

# 通过列表索引设置参数 my_list = ['菜鸟教程', 'www.runoob.com']

print("网站名:{0[0]}, 地址 {0[1]}".format(my_list)) # "0" 是必须的

open函数

python open() 函数用于打开一个文件,创建一个 file 对象

open(name[, mode[, buffering]])

参数说明:

name : 一个包含了你要访问的文件名称的字符串值。

mode : mode 决定了打开文件的模式:只读,写入,追加等。所有可取值见如下的完全列表。这个参数是非强制的,默认文件访问模式为只读(r)。

buffering : 如果 buffering 的值被设为 0,就不会有寄存。如果 buffering 的值取 1,访问文件时会寄存行。如果将 buffering 的值设为大于 1 的整数,表明了这就是的寄存区的缓冲大小。如果取负值,寄存区的缓冲大小则为系统默认。

all(iterable)

如果可迭代的对象(数组,字符串,列表等,下同)中的元素都是 true (或者为空)的话返回 True 。

if all(iterable):
    # do stuff

if all([1,2,3])
    Print(1)

>>>1

if all(1):
    print(1)

>>>'int' object is not iterable

any(iterable)

如果可迭代的对象中任何一个元素为 true 的话返回 True 。如果可迭代的对象为空则返回 False .

if any(iterable):
    # do stuff

 

dict([arg])

使用 arg 提供的条目生成一个新的字典。

如果我们想把一个含两个元组的列表转换成一个字典,我们可以这么做。

l = [('Knights', 'Ni'), ('Monty', 'Python'), ('SPAM', 'SPAAAM')]
d = dict()
for tuple in l:
    d[tuple[0]] = tuple[1]
# {'Knights': 'Ni', 'Monty': 'Python', 'SPAM': 'SPAAAM'}


a = [('a',1), ('b', 2), ('c', 3)] 
b = dict(a)
b
{'a': 1, 'b': 2, 'c': 3}

enumerate(iterable, [start=0])枚举对象

基本介绍:enumerate() 函数用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列,同时列出数据和数据下标,一般用在 for 循环当中。
enumerate(sequence, start=0)

sequence -- 一个序列、迭代器或其他支持迭代对象。
start -- 下标起始位置,默认为0。

for i in enumerate(list):      枚举后的,迭代出的单个对象为元组(tuple)

for index, value in enumerate(list):    索引与值分开

In [68]: isinstance(a, str)                                                           
Out[68]: True

enumerate() 函数用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列,同时列出数据和数据下标,一般用在 for 循环当中。

 a = 'asdfghjkl'                                                              

In [64]: for i in enumerate(a): 
    ...:     print(i) 

(0, 'a')
(1, 's')
(2, 'd')
(3, 'f')
(4, 'g')
(5, 'h')
(6, 'j')
(7, 'k')
(8, 'l')

isinstance(object, classinfo)

如果 object 参数是 classinfo 参数的一个实例或者子类(直接或者间接)的话返回 True 。

当你想检验一个对象的类型的时候,第一个想到的应该是使用 type() 函数。

In [68]: isinstance(a, str)                                                           
Out[68]: True

pow(x, y, [z])

函数是计算x的y次方,如果z在存在,则再对结果进行取模,其结果等效于pow(x,y) %z

In [70]: pow(2,4)                                                                     
Out[70]: 16

zip([iterable, ])

返回包含元组的列表

zip() 函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的列表。

如果各个迭代器的元素个数不一致,则返回列表长度与最短的对象相同,利用 * 号操作符,可以将元组解压为列表。

zip 方法在 Python 2 和 Python 3 中的不同:在 Python 3.x 中为了减少内存,zip() 返回的是一个对象。如需展示列表,需手动 list() 转换。

In [86]: a = [1,2,3,4]                                                                

In [87]: b = ['a','b','c']                                                            

In [88]: c = zip(a,b)                                                                 

In [89]: list(c)                                                                      
Out[89]: [(1, 'a'), (2, 'b'), (3, 'c')]

map()函数 

map()是 Python 内置的高阶函数,它接收一个函数 f 和一个 list,并通过把函数 f 依次作用在 list 的每个元素上,得到一个新的 list 并返回。

list1 = [1, 2, 3, 4, 5]
def f(x):
    return x**2
res = map(f, list1)

>>>[1, 4, 9, 16, 25]

注意:map()函数不改变原有的 list,而是返回一个新的 list。 利用map()函数,可以把一个 list 转换为另一个 list,只需要传入转换函数。 

 

Python里面match()和search()的区别?

答:re模块中match(pattern,string[,flags]),检查string的开头是否与pattern匹配。

re模块中re.search(pattern,string[,flags]),在string搜索pattern的第一个匹配值。

>>>print(re.match(‘super’, ‘superstition’).span())

(0, 5)

>>>print(re.match(‘super’, ‘insuperable’))

None

>>>print(re.search(‘super’, ‘superstition’).span())

(0, 5)

>>>print(re.search(‘super’, ‘insuperable’).span())

(2, 7)

如何用Python来进行查询和替换一个文本字符串?

答:可以使用re模块中的sub()函数或者subn()函数来进行查询和替换,

格式:sub(replacement, string[,count=0])(replacement是被替换成的文本,string是需要被替换的文本,count是一个可选参数,指最大被替换的数量)

>>> import re

>>>p=re.compile(‘blue|white|red’)

>>>print(p.sub(‘colour’,'blue socks and red shoes’))

colour socks and colourshoes

>>>print(p.sub(‘colour’,'blue socks and red shoes’,count=1))

colour socks and redshoes

subn()方法执行的效果跟sub()一样,不过它会返回一个二维数组,包括替换后的新的字符串和总共替换的数量

介绍一下except的用法和作用?

答:try…except…except…[else…][finally…]

执行try下的语句,如果引发异常,则执行过程会跳到except语句。对每个except分支顺序尝试执行,如果引发的异常与except中的异常组匹配,执行相应的语句。

如果所有的except都不匹配,则异常会传递到下一个调用本代码的最高层try代码中。

try下的语句正常执行,则执行else块代码。如果发生异常,就不会执行

如果存在finally语句,最后总是会执行。

什么是lambda函数?它有什么好处?

答:lambda 表达式,通常是在需要一个函数,但是又不想费神去命名一个函数的场合下使用,也就是指匿名函数

lambda函数:首要用途是指点短小的回调函数

lambda [arguments]:expression

>>> a=lambdax,y:x+y

>>> a(3,11)

匿名函数 lambda:是指一类无需定义标识符(函数名)的函数或子程序。lambda 函数可以接收
任意多个参数 (包括可选参数) 并且返回单个表达式的值。

例 1:传入多个参数的 lambda 函数
1. def sum(x,y):
2. return x+y
用 lambda 来实现:
1. p = lambda x,y:x+y
2. print(p(4,6))
例 2:传入一个参数的 lambda 函数
1. a=lambda x:x*x
2. print(a(3)) -------------------》注意:这里直接 a(3)可以执行,但没有输出的,前面的 print 不能少
例 3:多个参数的 lambda 形式:
1. a = lambda x,y,z:(x+8)*y-z
2. print(a(5,6,8))

 

Python里面如何拷贝一个对象?(赋值,浅拷贝,深拷贝的区别)

答:赋值(=),就是创建了对象的一个新的引用,修改其中任意一个变量都会影响到另一个。

浅拷贝:创建一个新的对象,但它包含的是对原始对象中包含项的引用(如果用引用的方式修改其中一个对象,另外一个也会修改改变){1,完全切片方法;2,工厂函数,如list();3,copy模块的copy()函数}

深拷贝:创建一个新的对象,并且递归的复制它所包含的对象(修改其中一个,另外一个不会改变){copy模块的deep.deepcopy()函数}

Python是如何进行内存管理的?

答:从三个方面来说,一对象的引用计数机制,二垃圾回收机制,三内存池机制

⒈对象的引用计数机制

Python内部使用引用计数,来保持追踪内存中的对象,所有对象都有引用计数。

引用计数增加的情况:

❶一个对象分配一个新名称

❷将其放入一个容器中(如列表、元组或字典)

引用计数减少的情况:

❶使用del语句对对象别名显示的销毁

❷引用超出作用域或被重新赋值

sys.getrefcount( )函数可以获得对象的当前引用计数

多数情况下,引用计数比你猜测得要大得多。对于不可变数据(如数字和字符串),解释器会在程序的不同部分共享内存,以便节约内存。

⒉垃圾回收 (标准答案:在python中,为了解决内存泄漏问题,采用对象引用计数,并基于引用计数实现自动垃圾回收。)

❶当一个对象的引用计数归零时,它将被垃圾收集机制处理掉。

❷当两个对象a和b相互引用时,del语句可以减少a和b的引用计数,并销毁用于引用底层对象的名称。然而由于每个对象都包含一个对其他对象的应用,

因此引用计数不会归零,对象也不会销毁。(从而导致内存泄露)。为解决这一问题,解释器会定期执行一个循环检测器,搜索不可访问对象的循环并删除它们。

⒊内存池机制

Python提供了对内存的垃圾收集机制,但是它将不用的内存放到内存池而不是返回给操作系统。

❶Pymalloc机制。为了加速Python的执行效率,Python引入了一个内存池机制,用于管理对小块内存的申请和释放。

❷Python中所有小于256个字节的对象都使用pymalloc实现的分配器,而大的对象则使用系统的malloc。

❸对于Python对象,如整数,浮点数和List,都有其独立的私有内存池,对象间不共享他们的内存池。也就是说如果你分配又释放了大量的整数,用于缓存这些整数的内存就不能再分配给浮点数。

GIL

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

fun(*args,**kwargs) 中的*args,**kwargs 什么意思?

*args 和 **kwargs 主要用于函数定义,可以将不定数量的参数传递给一个函数

不定数量是指预先不知道传进来多少个参数。

*args用来发送一个非键值对的可变数量的参数列表给一个函数。

def func(*args):
    for x in args:
        print(x)
func('a', 'b', 'c')

a
b
c

 **kwargs 允许将不定长度的键值对作为参数传递给一个函数,如果想要在一个函数里处理带名字的参数,应该使用**kwargs

def func2(**kwargs):
    for x, y in lwargs.items():
        print(x, y)

dunc2(name='a', 'age'=12, 'add'='c')

name a
age 12
add c

 

装饰器 decorator

函数可以作为参数传递的语言,可以使用装饰器

装饰器是Python中的特有变动,可以使修改函数变得更容易。

装饰器本质上是一个 Python函数,它可以让其它函数在不做任何变动的情况下增加额外功能,装饰器的返回值也是一个函数对象。他经常用于有切面需求的场景。比如:插入日志,性能测试,事务处理,缓存,权限校验等。有了装饰器我们就可以抽离出大量的与函数功能无关的雷同代码进行重用

帮助查找  python 的   bug 和进行静态的代码分析?

答:PyChecker 是一个 python 代码的静态分析工具,它可以帮助查找 python 代码的 bug, 并且会报告错误类型和复杂度
Pylint 是检验模块是否达到代码标准的另一个工具。

测试框架

unittest

nose

unittest2

doctest

pytest

底层网络交互模块

socket

urllib

urllib2

requests

grab

pycurl

数据库 varchar与char的区别是什么?大小限制?
​​​​​​

存数据时的区别
 char定义的是固定长度,长度范围为0-255,存储时,如果字符数没有达到定义的位数,会在后面用空格补全
 varchar是变长长度,长度范围为0-65535,存储时如果字符没有达到定义的位数,也不会在后面补空格,在
取数据时的区别
  数据库取char的数据时,会把后面的空格全部丢弃掉,也就是说在char中的尾部存入空格时,最后取出来都会被丢弃而数据库。。        在取varchar数据时尾部空格会保留.

__new__和__init__的区别?


init是当实例对象创建完成后被调用的,然后设置对象属性的一些初始值。
new是在实例创建之前被调用的,因为它的任务就是创建实例然后返回该实例,是个静态方法。
也就是,new在init之前被调用,new的返回值(实例)将传递给init方法的第一个参数,然后init给这个实例设置一些参数

Python 里面如何生成随机数?

random 模块
随机整数:random.randint(a,b):返回随机整数 x,a<=x<=b
random.randrange(start,stop,[,step]):返回一个范围在(start,stop,step)之间的随机整数,不包括结束值。
随机实数:random.random( ):返回 0 到 1 之间的浮点数
random.uniform(a,b):返回指定范围内的浮点数。

Python中单下划线和双下划线的区别?


 单下划线"开始的成员变量叫做保护变量,意思是只有类对象和子类对象自己能访问到这些变量;
  双下划线"开始的是私有成员,意思是只有类对象自己能访问,连子类对象也不能访问到这个数据。

如何判断单向链表中是否有环?


​​​​​​ 首先遍历链表,寻找是否有相同地址,借此判断链表中是否有环。如果程序进入死循环,则需要一块空间来存储指针,遍历新指针时将其和储存的旧指针比对,若有相同指针,则该链表有环,否则将这个新指针存下来后继续往下读取,直到遇见NULL,这说明这个链表无环

[[1,2], [3,4], [5,6]]  展开列表,得出[1,2,3,4,5,6]

方法一:思路

for i in list:
    for j in i:
        print(j)
    

合起来用列表生成式就是

[j for i in list for j in i]

 方法二:思路

numpy骚操作

flatten是numpy.ndarray.flatten的一个函数,即返回一个折叠成一维的数组。但是该函数只能适用于numpy对象,即array或者mat,普通的list列表是不行的。

tolist() 将数组或者矩阵转换成列表

import numpy as np
b = np.array(list).flatten().tolisst()

#列表-》矩阵-》列表

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值