‘壹’ python判断数据类型有几种方法,有啥优缺点
123456789
class A: passclass B(A): passa=A()b=B() print('a is an A:%s;b is an A:%s'%(isinstance(a,A),isinstance(b,A)))print('type of a is %s;type of b is %s'%(type(a),type(b)))
通常我们判断是什么类型,那么只是想直到这个对象是否含有我们所需要的方法或者属性,这样在调用的时候就不会出错,否则就要进行异常捕捉。而isinstance这个方法非常满足这个需求。以上是示例代码。
可以看出isinstance(a,A),isinstance(b,A)两个返回的都是True,如果我们把a,b都当做A的实例使用完全没问题,但是我们并不关心b是A的实例还是B的实例,因为他肯定包含A类定义中的所有属性和方法,正常调用不会出现异常。
type的话出来的则是一串字符串,精确到子类,所以可以用来做精确判断,例如判断是不是这个类,而不是这个类的子类,isinstance只能判断是不是这个类或者这个类的子类。
判断两个对象是否来自同一个类,可以用type(a)==type(b)来判断。
‘贰’ Python判断列表是否已排序的各种方法及其性能
本节判断列表排序的函数名格式为IsListSorted_XXX()。为简洁起见,除代码片段及其输出外,一律以_XXX()指代。
2.1 guess
def IsListSorted_guess(lst):
listLen = len(lst) if listLen <= 1: return True
#由首个元素和末尾元素猜测可能的排序规则
if lst[0] == lst[-1]: #列表元素相同
for elem in lst: if elem != lst[0]: return False
elif lst[0] < lst[-1]: #列表元素升序
for i, elem in enumerate(lst[1:]): if elem < lst[i]: return False
else: #列表元素降序
for i, elem in enumerate(lst[1:]): if elem > lst[i]: return False
return True
_guess()是最通用的实现,几乎与语言无关。值得注意的是,该函数内会猜测给定列表可能的排序规则,因此无需外部调用者指明排序规则。
2.2 sorted
def IsListSorted_sorted(lst):
return sorted(lst) == lst or sorted(lst, reverse=True) == lst
_sorted()使用Python内置函数sorted()。由于sorted()会对未排序的列表排序,_sorted()函数主要适用于已排序列表。
若想判断列表未排序后再对其排序,不如直接调用列表的sort()方法,因为该方法内部会判断列表是否排序。对于已排序列表,该方法的时间复杂度为线性阶O(n)——判断为O(n)而排序为O(nlgn)。
2.3 for-loop
def IsListSorted_forloop(lst, key=lambda x, y: x <= y):
for i, elem in enumerate(lst[1:]): #注意,enumerate默认迭代下标从0开始
if not key(lst[i], elem): #if elem > lst[i]更快,但通用性差
return False
return True
无论列表是否已排序,本函数的时间复杂度均为线性阶O(n)。注意,参数key表明缺省的排序规则为升序。
2.4 all
def IsListSorted_allenumk(lst, key=lambda x, y: x <= y):
return all(key(lst[i], elem) for i, elem in enumerate(lst[1:]))import operatordef IsListSorted_allenumo(lst, oCmp=operator.le):
return all(oCmp(lst[i], elem) for i, elem in enumerate(lst[1:]))def IsListSorted_allenumd(lst):
return all((lst[i] <= elem) for i, elem in enumerate(lst[1:]))def IsListSorted_allxran(lst, key=lambda x,y: x <= y):
return all(key(lst[i],lst[i+1]) for i in xrange(len(lst)-1))def IsListSorted_allzip(lst, key=lambda x,y: x <= y):
from itertools import izip #Python 3中zip返回生成器(generator),而izip被废弃
return all(key(a, b) for (a, b) in izip(lst[:-1],lst[1:]))
lambda表达式与operator运算符速度相当,前者简单灵活,后者略为高效(实测并不一定)。但两者速度均不如列表元素直接比较(可能存在调用开销)。亦即,_allenumd()快于_allenumo()快于_allenumk()。
若使用lambda表达式指示排序规则,更改规则时只需要改变x和y之间的比较运算符;若使用operator模块指示排序规则,更改规则时需要改变对象比较方法。具体地,lt(x, y)等效于x < y,le(x, y)等效于x <= y,eq(x, y)等效于x == y,ne(x, y)等效于x != y,gt(x, y)等效于x > y,ge(x, y)等效于x >= y。例如,_allenumo()函数若要严格升序可设置oCmp=operator.lt。
此外,由all()函数的帮助信息可知,_allenumk()其实是_forloop()的等效形式。
2.5 numpy
def IsListSorted_numpy(arr, key=lambda dif: dif >= 0):
import numpy try: if arr.dtype.kind == 'u': #无符号整数数组执行np.diff时存在underflow风险
arr = numpy.int64(lst) except AttributeError: pass #无dtype属性,非数组
return (key(numpy.diff(arr))).all() #numpy.diff(x)返回相邻数组元素的差值构成的数组
NumPy是用于科学计算的Python基础包,可存储和处理大型矩阵。它包含一个强大的N维数组对象,比Python自身的嵌套列表结构(nested list structure)高效得多。第三节的实测数据表明,_numpy()处理大型列表时性能非常出色。
在Windows系统中可通过pip install numpy命令安装NumPy包,不建议登录官网下载文件自行安装。
2.6 rece
def IsListSorted_rece(iterable, key=lambda x, y: x <= y):
cmpFunc = lambda x, y: y if key(x, y) else float('inf') return rece(cmpFunc, iterable, .0) < float('inf')
rece实现是all实现的变体。累加器(accumulator)中仅存储最后一个检查的列表元素,或者Infinity(若任一元素小于前个元素值)。
前面2.1~2.5小节涉及下标操作的函数适用于列表等可迭代对象(Iterable)。对于通用迭代器(Iterator)对象,即可以作用于next()函数或方法的对象,可使用_rece()及后面除_rand()外各小节的函数。迭代器的计算是惰性的,只有在需要返回下一个数据时才会计算,以避免不必要的计算。而且,迭代器方式无需像列表那样切片为两个迭代对象。
2.7 imap
def IsListSorted_itermap(iterable, key=lambda x, y: x <= y):
from itertools import imap, tee
a, b = tee(iterable) #为单个iterable创建两个独立的iterator
next(b, None) return all(imap(key, a, b))
2.8 izip
def IsListSorted_iterzip(iterable, key=lambda x, y: x <= y):
from itertools import tee, izip
a, b = tee(iterable) next(b, None) return all(key(x, y) for x, y in izip(a, b))def pairwise(iterable):
from itertools import tee, izip
a, b = tee(iterable) next(b, None) return izip(a, b) #"s -> (s0,s1), (s1,s2), (s2, s3), ..."def IsListSorted_iterzipf(iterable, key=lambda x, y: x <= y):
return all(key(a, b) for a, b in pairwise(iterable))
第三节的实测数据表明,虽然存在外部函数调用,_iterzipf()却比_iterzip()略为高效。
2.9 fast
def IsListSorted_fastd(lst):
it = iter(lst) try:
prev = it.next() except StopIteration: return True
for cur in it: if prev > cur: return False
prev = cur return Truedef IsListSorted_fastk(lst, key=lambda x, y: x <= y):
it = iter(lst) try:
prev = it.next() except StopIteration: return True
for cur in it: if not key(prev, cur): return False
prev = cur return True
_fastd()和_fastk()是Stack Overflow网站回答里据称执行最快的。实测数据表明,在列表未排序时,它们的性能表现确实优异。
2.10 random
import randomdef IsListSorted_rand(lst, randNum=3, randLen=100):
listLen = len(lst) if listLen <= 1: return True
#由首个元素和末尾元素猜测可能的排序规则
if lst[0] < lst[-1]: #列表元素升序
key = lambda dif: dif >= 0
else: #列表元素降序或相等
key = lambda dif: dif <= 0
threshold, sortedFlag = 10000, True
import numpy if listLen <= threshold or listLen <= randLen*2 or not randNum: return (key(numpy.diff(numpy.array(lst)))).all() from random import sample for i in range(randNum):
sortedRandList = sorted(sample(xrange(listLen), randLen))
flag = (key(numpy.diff(numpy.array([lst[x] for x in sortedRandList])))).all()
sortedFlag = sortedFlag and flag return sortedFlag
_rand()借助随机采样降低运算规模,并融入其他判断函数的优点。例如,猜测列表可能的排序规则,并在随机采样不适合时使用相对快速的判断方式,如NumPy。
通过line_profiler分析可知,第20行和第21行与randLen有关,但两者耗时接近。因此randLen应小于listLen的一半,以抵消sorted开销。除内部限制外,用户可以调节随机序列个数和长度,如定制单个但较长的序列。
注意,_rand()不适用于存在微量异常数据的长列表。因为这些数据很可能被随机采样遗漏,从而影响判断结果的准确性。
‘叁’ 用python编写:查找字母。设有英文字母串变量s,用for测试s中是否包含a字母
可以不用for,用find,没有就返回-1,有的话返回位置:s.find('a')
for的话这样写:
def findsth(s):
----for i in s:
--------if i == 'a': return True
----return False
‘肆’ python常见数据类型
一,python整数类型所表示的数据。
1,一般用以表示一类数值:所有正整数,0和负整数;
2,整型作为最常用的,频繁参与计算的数据类型,在python3.5中解释器会自动在内存中创建-5-3000之间的(包含5,不包含3000)整型对象,也就是说在该范围内,相等都是同一个已经创建好的整型对象。范围之外的即使相等也表示不同对象,该特性随python版本而改变,不要过于依赖。
3,bool型继承了int型,他是int的子类。
4,Python2中有长整型long,数值范围更大,在python3中已取消,所有整型统一由int表示。
5,参与所有数值计算,数学运算,科学计算。这也是所有编程语言都有的数据类型,因为编程语言生而需要模拟人的思维,借助数学方式,自动计算、更好的解决大量重复性的事务,因此数值类型、整数类型在编程语言中不可或缺。
6,支持二进制(0b\0B开头),十进制,八进制(0o\0O),十六进制(0x\0X)
二,python整数和浮点型支持常规的数值运算
整数和浮点数都可参与的运算:+ - * / %(取余) //(整除) **(幂)
Python字符型:
python字符型表示的数据:
python3支持Unicode编码,由字母、数字和符号组成的形式就叫字符串,更接近或者相同与人们文字符号表示,因此在信息表示和传递时它也是最受认可的形式。在程序编写中也是非常常用,对应的可操作的方法也很多,很有意思。
字符串不可被修改,可以拼接等方法创建新字符串对象;
支持分片和下标操作;a[2:]
支持+拼接,*重复操作和成员关系in/not in;
表示形式:用单引号双引号包含起来的符号;a = str(‘sdfsdfsdf’) 或 r’\t\nabcd’ 原始字符,Bytes:b’abcd’;
6,字符串属于不可变数据类型,内部机制为了节省空间,相同的两个字符串表示相同的一个对象。a = ‘python’ b = ‘python’ a is b :True
二, 字符串支持的运算方法
1,capitalize() :首字母大写后边的字母小写 a = ‘abcd’ b = a.capitalize() b:Abcd
2,casefold() lower():字母转换为全小写
3,center(width,fillchar) :居中,width填补的长度;fillchar添加的字符
a = a.center(10,’_’) //’____abcd____’ 默认无fillchar填充空格
4,count(sub,star,end) :字母计数:sub要查询的字符
5,encode(encoding=’utf-8’,errors=’strict’) 设置编码
Errors :设置错误类型
6,endswith(suffix,star,end) : 若以suffix结尾返回True
7,expandtabs(8) :设置字符串中tab按键符的空格长度:’\tabcde’
8,find(sub,star,end) : 返回指定范围内的字符串下标,未找到返回-1
9,index(sub,star,end) :返回指定范围字符串下标未找到抛出异常
10,isalnum() :判断字符串是否是字母或数字,或字母和数字组合
11,isalpha() :判断是否全是字母
12,isdecimal() :判断字符串是否是十进制数值
13,isdigit() :判断字符串是否是数字
14,isidentifier() :判断字符串中是否包含关键字
15,islower() :判断是否全小写
16,isnumeric() :判断全是数字
17,isspace() :判断是否是空格
18,isupper() 判断是否大写
19,istitle() :判断是否首字母大写
20,join(iterable) :把可迭代对象用字符串进行分割:a.join(‘123’)
21,ljust(width,fillchar);rjust() :左对齐右对齐
22, upper() :将字符串改为大写
23,split(sep=None,maxsplit=-1) :分割一个字符串,被选中字符在字符串中删除
‘ab1cd1efg’.split(‘1’) :[‘ab’,’cd’,’efg’]
三,字符串格式化:按照规格输出字符串
format(*args,**kwargs) :args位置参数,kwargs关键字参数
‘{0:.1f}’.format(123.468) :格式化参数,小数点后保留1位四舍五入
四,字符串操作符%
1,%s :格式化字符串 ‘abcd%sdef’%’dddd’
2,%d:格式化整数
3,%o格式化无符号八进制
4,%x格式化无符号十六进制
5,%f格式化定点数
6, %e: 科学计数法格式化定点数
7,%g 根据值大小自动选%f,%e
8, %G E X :大写形式
五,格式化辅助命令:
m.n :m最小总宽度,n小数点后位数:’%12.4f’%23456.789
六,转义字符:字符串前r避免转义:r’\nhello\thi’
\n:换行符
\t:横向制表符
\':'
\":"
\b:退格符
\r:回车
\v:纵向制表符
\f:换页符
\o,\x:八进制和十六进制
\0:空字符串
Python列表list
一,Python的列表list类型表示的数据:
Python列表在cpython中被解释为长度可变的数组,用其他对象组成的连续数组。
列表中元素可以是相同或不同的数据类型;
当列表元素增加或删除时,列表对象自动进行扩展或收缩内存,保证元素之间没有缝隙,总是连续的。
Python中的列表是一个序列,也是一个容器类型
创建列表:a = []; b = [1,’python’]; c = list(); d = list((1,3,4,5))
支持切片操作list[start,stop,step]
python列表常用方法
1,append添加单个元素:list.append(object); //a.append(‘python’)
2,extend添加可迭代对象: list.extend(iterable); //a.extend(‘abcde’/[1,2,3])
3,insert 插入元素:list.insert(index,object): 在index下标前插入元素//a.insert(2,’python’)
4,clear 清空所有元素:list.clear() //a.clear()
5,pop 删除并返回一个元素:list.pop(index) //默认删除默认一个元素
remove 删除指定元素:list.remove(v) ,v元素不存在报错 //a.remove(‘c’)
7,count 返回这个值在列表中数量:list.count(value)
8, 浅拷贝一个新列表:list.()
9,sort:排序list.sort(reverse=False/True) :默认升序
排序函数:sorted(list)
10,reverse: 原地翻转:list.reverse()
11,index(value,star,stop) :指定范围内该值下标:list.index(2,0,5)
列表元素访问:
下标访问:list[1]
For循环遍历
通过下标修改元素:list[2 ] = ‘hello’
列表常用运算符:
1,比较运算符:从第一个元素开始对比
2,+ 拼接一个新列表:l1+ l2
3, 重复操作符:* ,多个列表拼接
成员关系操作符:in/ not in
逻辑运算符:and not or
列表常用的排序方法:
冒泡排序;选择排序;快速排序;归并排序
Python元组tuple
一,Python元组tuple数据类型表示的数据:
元组是受到限制的、不可改变的列表;
可以是同构也可以是异构;
元组是序列类型、是可迭代对象,是容器类型。
元组的创建: a = (1,2,3)或a=1,2,3; b = tuple(); c = tuple(iterable)
支持切片操作tuple[start,stop,step]
二,python元组常用方法
1,index(value,star,stop) :指定范围内该值下标:tuple.index(2,0,5)
2,count(value) :值出现次数
三,支持运算:
1,比较运算符:从第一个元素开始对比
2,+ 拼接一个新元组:l1+ l2
3, 重复操作符:* ,多个元组拼接
4成员关系操作符:in/ not in
逻辑运算符:and not or
四,元组的访问
下标操作;
For循环遍历访问。
Python字典类型
一,Python字典dict表示的数据:{key:value}
可根据关键字:键快速索引到对应的值;
字典是映射类型,键值对一一对应关系,不是序列;
字典元素是无序的;
字典是可迭代对象,是容器类型;
字典的创建:k = {}; k1={‘keyword’:object}; k2 = dict();
K3 = dict(mapping); dict=(iterable)
二,字典的访问:
通过key:k[‘key’]
修改key对应的值:K[‘key’] = value
For循环遍历出来的是key;
For循环键值对:for I in d.items():
For 循环enumerate: for k,v in enumerate(k1):
In/not in 成员关系查询键不支持查值
三,字典常用方法
get(key,de):获取值:k.get(key,de) //若不存在则默认输出de
pop(k,de):删除一个键值对,不存在输出de,未设置报错;
keys() :返回字典所有key组成的序列:list(k.keys()) [1,2,3];
values():返回字典所有value组成的序列:list(k.values())
items():返回键值对组成的元组为元素的序列:(类set)list(k.items())
update(e):更新字典:e可是字典或两元素组成的单位元素序列:e=[(5,6),(7,8)];
k.update(e)
clear():清空字典;
popitem()删除某个键值对,若字典为空则报错
() :浅拷贝
10, fromkeys(iterable,value=None):从可迭代对象创建字典
{}.fromkeys([1,2,3]) -----{1:None,2:None,3:None}
11,setdefault(k,d=None) :若key不存在则生成一个键值对
k.setdefault(‘keyword’)
Python 集合set
集合表示的数据:
多个元素的无序组合,集合是无序的,集合元素是唯一的;
字典的键是由集合实现的;
集合是可迭代对象
集合创建:s = {1,2}; s1 = set(); s2 = set(iterable)
集合元素的访问:
For 循环将集合所有元素全部访问一遍,不重复
常用方法:
add(object):s.add(‘hi’) 向集合添加一个元素
pop() :弹栈,集合为空则报错:删除任意一个元素;
clear():清空集合,返回一个空集合对象;
remove(object):删除一个元素,不存在和报错:s.remove(‘hi’)
update(集合):更新另一个集合,元素不存在则不更新;
() :浅拷贝
集合的运算:
交集:s1&s2;
差集,补集:s1-s2;
并集:s1|s2;
Issubset():判断是否是子集:s1.issubset(s2) s1是否s2的集合子集
Issuperset():判断是否是父集:s1.issuperset()
不可变集合:
Frozenset():返回一个空的不可变集合对象
Frozenset(iterable):
S = frozenset(iterable)
Python序列类型共同特性
一,序列类型共同特性
python序列类型有:str字符串,list列表,tuple元组
都支持下标索引,切片操作;
下标都是从0开始,都可通过下标进行访问;
拥有相同的操作符
二,支持的函数:
len(obj):返回对象长度;
list(iterable):将可迭代对象转为列表;
tuple(iterable):将可迭代对象转为元组;
str(ojb):将任何对象转为字符串形式;
max(iterable): python3中元素要是同类型,python2中元素可异构:max([‘a’,1])
min(iterable):和max类似;
sum(iterable,star=0),求可迭代对象和,默认star为0,元素不能为字符串
sorted(iterable,key=None,reverse=False)
s=[(‘a’,3),(‘b’,2),(‘c’,9)]
sorted(s,key=lambda s:s[1]) //按照数字排序
reversed(sequence):翻转序列,返回迭代器
enumerate(iterable):返回enumerate对象,其元素都是一个元组(下标,值)
zip(iter1,iter2): zip([1,2],[3,4]) ----[(1,3),(2,4)]
序列类型的切片操作:
Slice:
L[index]; 访问某个元素;
L[1:4]; 区间
L[star:stop:step]; 设置步长取区间元素
‘伍’ 浅谈python中的变量赋值
在python中,变量赋值的语法比较简单,语法就是 “变量名 = 对象”,由于python属于动态语音,所以不需要像c、 java那样在变量赋值时需要声明变量的类型。
c 变量赋值
int x = 1;
python 变量赋值
x = 1
y = "hello world!"
a = [1, 2]
b = ('a', 'b')
c = {"foo": "bar"}
python 变量赋值中,所涉及到的变量命名是有一定规则的:
1. 变量名只能包含字母、数字和下划线。变量名可以字母或下划线开头,但不能以数字开头,例如,可将变量命名为name_1,但不能将其命名为1_name
2. 变量名不能包含空格,但可使用下划线来分隔其中的单词。例如,变量名name_one可行,但变量名name one会引发错误。
3. 不要将Python关键字和函数名用作变量名,即不要使用Python保留用于特殊用途的单词,如not、pass等。
4. 变量名应既简短又具有描述性。例如,name比n好,student_name比s_n好,name_length比length_of_persons_name好, 虽说简短好,但是不能依照自己的意愿随意简写,尽量使用大家约定俗成的简写,如果不是还不如写全拼。
5. python 变量名中大小写敏感,所以 NAME, Name, name 代表三个不同的表里名, 这里提一下就是慎用小写字母l和大写字母O,因给他们可能被人错看成数字1和0;
再说变量赋值中赋予给变量的值,python中万事皆对象,所以python中只要是对象就能给变量赋值。如:
x = 1 # x赋值为数字1;
x = sum # x赋值为内建求和函数sum;
python的赋值真实上说应该不是赋值,而更像是“引用”,如何理解“引用”呢,python中一直对象的生成是会在内存中分配给一个内存地址,这个内存地址可以使用id()方法去获取,然后在变量赋值时,将变量直接引用该对象的内存地址,进而完成变量赋值,如:
x = 1, 赋值时x直接引用1所在内存的地址, y = x, 此时是y直接引用x的所指向的内存地址
python中有判断变量的方法如 is() 和 ==,二者在判断变量时是有区别的,is函数是判断变量的内存地址是否相同,而 == 是判断变量的值是否相同,举例说明:
a = 1; b = 1.0
a is b # False
a == b # True
小心python变量赋值的陷阱
看到上面的所述知道了python变量赋值实则是引用,引用的是对象的内存地址。所赋的值可以分两类,一类是可变的,如列表,字典,集合;一类是不可变的,如字符串、元组。所以当对象为可变类型时就会出现一种情景,我们举例说明:
x = [1, 2, 3]
y = x
print x == y # True
print x is y # True
print x # [1, 2, 3]
print y # [1, 2, 3]
y.append(4)
print x # [1, 2, 3, 4]
print y # [1, 2, 3, 4]
可以看到y在进行调整时(添加了一个元素),x也跟着变动了,这进一步说明了,python中的变量赋值时引用,x,y 赋值时指向了同一处内存地址,所以当y变动时,x同样也发送了变化,解决这中现象的方法可以是x, y = [1,2,3], [1,2,3]这样赋值,虽说此时 x==y 是True,但是确实是2个不同的内存地址,所以 x is y 则是 False。或者可以使用模块,实质是相同的,创建2个不同的内存地址,使其分离。
‘陆’ python判断元素是否在列表组中
locals()函数会以字典类型返回当前位置的全部局部变量。
对于函数, 方法, lambda 函式, 类, 以及实现了 __call__ 方法的类实例, 它都返回 True。
def chuli():
list1 = ['A', 'B1', 'C', 'D6', 'E2', 'F4']
list2 = ['G', 'H', 'K45', 'J4', 'K', 'L7']
list3 = ['M3', 'N', 'O5', 'P', 'Q43', 'R']
# 在这里有100个列表
list100 = ['S2', 'W5', 'R8', 'T', 'W', 'E']
# locals() 函数会以字典类型返回当前位置的全部局部变量。
# 对于函数, 方法, lambda 函式, 类, 以及实现了 __call__ 方法的类实例, 它都返回 True。
dc = locals()
for key, val in dc.items():
if 'K45' in val:
print(key)
chuli()