1、如何调整字符串中文本的格式?
方法:使用 re.sub
In [113]: import re
In [111]: day = '2017-07-24'
In [115]: re.sub('(\d{4})-(\d{2})-(\d{2})',r'\2/\3/\1',day)
Out[115]: '07/24/2017'
2、如何将多个小字符串拼接成一个大字符串?
方法一:使用 “+” 操作符
In [118]: s = ['sdfdsfs','sdfewv','cvxbxcz','yetruywow']
In [119]: string = ''
In [120]: for st in s:
...: string+=st
...: print string
sdfdsfs
sdfdsfssdfewv
sdfdsfssdfewvcvxbxcz
sdfdsfssdfewvcvxbxczyetruywow # 此方法会有较大的内存消耗
方法二:使用 str.join
In [118]: s = ['sdfdsfs','sdfewv','cvxbxcz','yetruywow']
In [121]: ''.join(s)
Out[121]: 'sdfdsfssdfewvcvxbxczyetruywow'
In [122]: s1 = ['dsd','adev',6545,7711,'ewrewc']
In [123]: ''.join((str(x) for x in s1)) # 对有数字的列表进行处理
Out[123]: 'dsdadev65457711ewrewc'
3、如何对字符串进行左、右、居中对齐?
方法一:使用 str.ljust,str.rjust,str.center
In [124]: s = 'going'
In [125]: s.ljust(20,'-')
Out[125]: 'going---------------'
In [126]: s.rjust(20,'-')
Out[126]: '---------------going'
In [127]: s.center(20,'-')
Out[127]: '-------going--------'
In [133]: d = {'housename':'marryCenter','width':30,'height':20.55,'long':30}
In [137]: for k in d:
...: print k.ljust(max(map(len,d.keys()))),':',d[k]
width : 30
housename : marryCenter
long : 30
height : 20.55
方法二:使用 format
In [130]: format(s,'<20')
Out[130]: 'going '
In [131]: format(s,'>20')
Out[131]: ' going'
In [132]: format(s,'^20')
Out[132]: ' going '
4、如何去掉字符串中不需要的字符?
方法一:使用 strip
In [145]: s = '///abc*****'
In [148]: s.strip('/*')
Out[148]: 'abc'
方法二:切片拼接
In [149]: s = 'carry?me'
In [151]: s[:5]+s[6:]
Out[151]: 'carryme'
方法三:使用 str.replace
In [152]: s = 'sweep\nhouse\n'
In [154]: s.replace('\n','')
Out[154]: 'sweephouse'
方法四:使用 re.sub
In [158]: s = 'oh\tmy\ngod'
In [159]: re.sub('[\t\n]','',s)
Out[159]: 'ohmygod'
方法五:使用 str.translate
In [165]: s = 'not\na\tfellower\r'
In [167]: s.translate(None,'\t\r\n')
Out[167]: 'notafellower'
5、如何派生内置不可变类型并修改实例化行为?
方法:实现 __new__ 方法
例子:将列表中的数字筛选出来。
In [6]: class IntTuple(tuple):
...: def __new__(cls,iterable):
...: l = (x for x in iterable if isinstance(x,int))
...: return super(IntTuple,cls).__new__(cls,l)
...: def __init__(self,iterable):
...: super(IntTuple,self).__init__(iterable)
In [7]: t = IntTuple([1,0,-1,7,'HAH'])
In [8]: print t
(1, 0, -1, 7)
tips:实例由内置方法__new__创建,所以修改__new__方法就可实现新型元组。
6、如何为创建大量实例节省内存?
方法:定义类的__slot__属性
例子:定义一个学生类的两种方法
In [12]: class Student1(object):
...: def __init__(self,mid,name,age,sex):
...: self.mid = mid
...: self.name = name
...: self.age = age
...: self.sex = sex
In [13]: class Student2(object): # 多了一个__slots__属性
...: __slots__ = ['mid','name','age','sex']
...: def __init__(self,mid,name,age,sex):
...: self.mid = mid
...: self.name = name
...: self.age = age
...: self.sex = sex
In [14]: s1 = Student1('01','kim','20','male')
In [16]: s2 = Student2('01','kim','20','male')
In [21]: set(dir(s1)) - set(dir(s2))
Out[21]: {'__dict__', '__weakref__'}# Student1比Student2多出两个属性,所以内存占用方面会比较大
In [23]: s1.email = '[email protected]' # Student1支持动态绑定
In [24]: s1.__dict__
Out[24]:
{'age': '20',
'email': '[email protected]',
'mid': '01',
'name': 'kim',
'sex': 'male'}
In [28]: s2.email = '[email protected]' # Student2不支持动态绑定
AttributeError: 'Student2' object has no attribute 'email'
tips:__slots__属性可以节省__dict__属性,并且不支持动态绑定,从而达到减少内存开销的目的。
7、如何让类支持比较操作?
方法一:类内部实现__lt__,__le__,__gt__,__ge__,__eq__, __ne__
In [36]: class Rectangle(object):
...: def __init__(self,width,height):
...: self.width = width
...: self.height = height
...: def area(self):
...: return self.width*self.height
...: def __gt__(self,obj): # 大于
...: print '__gt__'
...: return self.area() > obj.area()
...: def __eq__(self,obj): # 等于
...: print '__eq__'
...: return self.area() == obj.area()
In [37]: r1 = Rectangle(5,5)
In [38]: r2 = Rectangle(4,6)
In [39]: r1 > r2
__gt__
Out[39]: True
In [40]: r1 == r2
__eq__
Out[40]: False
方法二:使用 total_ordering 简化
In [43]: from functools import total_ordering
In [44]: @total_ordering
...: class Rectangle(object):
...: def __init__(self,width,height):
...: self.width = width
...: self.height = height
...: def area(self):
...: return self.width*self.height
...: def __lt__(self,obj): # 小于
...: print '__lt__'
...: return self.area() < obj.area()
...: def __eq__(self,obj): # 等于
...: print '__eq__'
...: return self.area() == obj.area()
In [45]: r1 = Rectangle(5,6)
In [46]: r2 = Rectangle(3,9)
In [47]: r1 > r2 # 可以使用大于
__lt__
__eq__
Out[47]: True
tips:使用 @total_ordering 修饰,可以根据给出的两个运算符进行推导。
方法二升级:定义一个基类支持多类型比较
In [48]: from abc import ABCMeta,abstractmethod
...: @total_ordering
...: class Shape(object):
...: @abstractmethod #子类必须实现的方法
...: def area(self):
...: pass
...: def __lt__(self,obj):
...: print '__lt__'
...: if not isinstance(obj,Shape):#判断类型是否有误
...: raise TypeError('obj is not Shape!')
...: return self.area() < obj.area()
...: def __eq__(self,obj):
...: print '__eq__'
...: if not isinstance(obj,Shape):
...: raise TypeError('obj is not Shape!')
...: return self.area() == obj.area()
In [49]: class Rectangle(Shape):
...: def __init__(self,width,height):
...: self.width = width
...: self.height = height
...: def area(self):
...: return self.width*self.height
In [50]: class Circle(Shape):
...: def __init__(self,r):
...: self.r = r
...: def area(self):
...: return self.r**2*3.14
In [51]: r1 = Rectangle(9,5)
In [52]: c1 = Circle(4)
In [53]: print r1 > c1
__lt__
False
tips:通过定义基类,可以比较多种类的面积大小,就达到简化程序的目的。
8、如何在一个 for 语句中迭代多个可迭代对象?
方法一:zip 函数进行并行操作
例子:同时迭代4个列表
In [71]: data1 = [randint(60,100) for _ in xrange(10)]
In [72]: data2 = [randint(60,100) for _ in xrange(10)]
In [73]: data3 = [randint(60,100) for _ in xrange(10)]
In [75]: data4 = [randint(60,100) for _ in xrange(10)]
In [74]: for x,y,z,r in zip(data1,data2,data3,data4):# 解包
...: total = x+y+z+r
...: print total
198
238
234
235
...
方法二:使用 chain 进行串行操作
例子:数据同上,统计大于80的项
In [78]: from itertools import chain
In [79]: count = 0
In [81]: for s in chain(data1,data2,data3,data4):
...: if s>80:
...: count += 1
...:
In [82]: count
Out[82]: 17