测试一个对象是否是类字符串
isinstance
type(obj) == type(”)
try:
obj + ''
except:
return False
else:
return True
字符串对齐
string.ljust(width,fill)
string.rjust(width,fill)
string.center(width,fill)
去除字符串中包含的空格
string.lstrip()
string.rstrip()
string.strip()
反转字符串
rewords = words[::-1]
rewords = words.split()
rewords.reverse()
rewords = ' '.join(rewords)
re.split(pattern,astring)
string.maketrans string.translate 过滤字符串中的某些字符
keep = ‘abcd’
all_chars = string.maketrans(”,”) #创建translate table
del_chars = all_chars.translate(all_chars,keep)
s.translate(all_chars,del_chars)
判断字符串是二进制还是文本
import string
from __future__ import division
text_chars = ''.join(map(chr,range(32,127)))
null_trans = string.maketrans('','')
def isText(s,text_chars=text_chars,threshold=0.3):
if '\0' in s:
return False
if not s:
retunr True
not_text_chars =s.translate(null_trans,text_chars)
return len(not_text_chars)/len(s) <= threshold
字符串方法:upper() lower() title() capitalize() isupper() islower() istitle()
访问(分割字符串)子字符串
struct.unpack('3s 5s 4s','asdqwertzxcv') #return ('asd', 'qwert', 'zxcv')
def cut(L,cuts):
start = 0
end = 0
for x in cuts:
end = start + x
if end <= len(L):
print L[start:end]
start = end
elif start < len(L):
print L[start:]
break
else:
break
重新调整行首空格
def reindent(s,numSpace):
leading_space = numSpace * ' '
lines = [leading_space + line.strip() for line in s.splitlines()]
return '\n'.join(lines)
替换字符串中某些子字符串
‘%(name)s aegfwg’ % {‘name’:’replace’}
t = string.Template(‘$name agg’)
t.substitute({‘name’:’replace’})
for line_num,line in enumerate(open(thefilepath,'r'),1):
if line_num == the_desire_line_num:
res = line
统计文本文件行数
len(open(thefilepath,'r').readlines())
count = -1
for count,line in enumerate(open(thefilepath,'r')):
pass
count += 1
tempfile和zipfile的使用。从zipfile中导入模块
import os,sys,tempfile,zipfile
fd,filename = tempfile.mkstemp(suffix='.zip')
os.close(fd)
zf = zipfile.ZipFile(filename,'w')
zf.writestr('hello.py','def func():return "Hello world from " + __file__\n')
zf.close()
sys.path.insert(0,filename)
import hello
print hello.func()
向windows标准输出输出二进制数据
python在一般情况下是以文本模式打开sys.stdout的,要输出二进制数据可以使用msvcrt模块
import sys
if sys.platform == 'win32':
import msvcrt,os
msvcrt.setmode(sys.stdout.fileno(),os.BINARY)
使用C++的类iostream的语法
class IOStream(object):
def __init__(self,output=None):
if output is None:
import sys
output = sys.stdout
self.output = output
self.format = '%s'
def __lshift__(self,thing):
if isinstance(thing,IOManipulator):
thing.do(self)
else:
self.output.write(self.format % thing)
self.format = '%s'
return self
class IOManipulator(object):
def __init__(self,callback_func):
self.func = callback_func
def do(self,stream):
self.func(stream)
#处理换行
def do_endl(stream):
stream.output.write('\n')
stream.output.flush()
endl = IOManipulator(do_endl)
#处理字符串格式化,%x16进制
def format_hex(stream):
stream.format = '%x'
fhex = IOManipulator(format_hex)
# ----test----------
def test():
count = IOStream()
count << 'like C++\'s class IOStream'
if __name__ == '__main__':
test()
给定两个目录,计算出目录1相对于目录2的相对目录
例如:/a/b/c/d,/a/b/e/f/g,返回../../e/f/g
import os
def all_equal(elements):
return len(set(elements)) == 1
def common_prefix(*sequences):
common = []
if not sequences:
return [],[]
for elements in zip(*sequences):
if not all_equal(elements):
break
common.append(elements[0])
return common,[sequence[len(common):] for sequence in sequences]
def relpath(path1,path2,sep=os.path.sep,pardir=os.path.pardir):
common,[u1,u2] = common_prefix(path1.split(sep),path2.split(sep))
if not common:
return path2
return sep.join([pardir] * len(u1) + u2)
def test(path1,path2,sep=os.path.sep):
print 'from','<',path1,'>','to','<',path2,'>','==>',relpath(path1,path2)
if __name__ == '__main__':
test('/root/etc/python27/read.txt','/root/etc/mysql/config.cfg','/')
test('/home/lxy/a/b/c.txt','/home/lxy/r/n/g.txt','/')
test(r'',r'C:\MinGW\include\_mingw.h')
文件版本化,在编辑文件之前,生成一个该文件的拷贝
def versionFile(file_spec,vtype='copy'):
import os,shutil
if os.path.isfile(file_spec):
if vtype not in ('copy','rename'):
raise ValueError,'Unknow vtype %r' % vtype
root,ext = os.path.splitext(file_spec)
if len(ext) == 4 and ext[1:].isdigit():
version_num = int(ext[1:]) + 1
else:
version_num = 0
for i in xrange(version_num,100):
new_file = '%s.%03d' % (root,i)
if not os.path.exists(new_file):
if vtype == 'copy':
shutil.copy(file_spec,new_file)
else:
os.rename(file_spec,new_file)
print '%s successful' % vtype
return True
raise RuntimeError,'Can\'t %s %r,all names taken' % (vtype,file_spec)
else:
print '%s is not a file' % file_spec
return False
if __name__ == '__main__':
versionFile('test','rename')
GMT时间表示格林威治时间,也就是UTC(世界标准时间)
time.gmttime([sec])–>sec表示从纪元(Epoch:1970/1/1 0:0:0)到现在的秒数,返回时间元组(tm_year,tm_mon,tm_mday,tm_hour,tm_min,
tm_sec,tm_wday,tm_yday,tm_isdst)。
time.localtime([sec])–>将世界标准时间转换为本地时区的时间。
time.asctime([tuple])–>tuple:时间元组,返回字符串格式的时间。若tuple缺省,默认使用time.localtime()返回的时间元组。
time.strftime(format[, tuple]) -> string
将时间元组转换为格式化字符串,tuple默认使用localtime()返回的时间元组。
format
Directive | Meaning | Notes |
---|---|---|
%a | Locale’s abbreviated weekday name. | |
%A | Locale’s full weekday name. | |
%b | Locale’s abbreviated month name. | |
%B | Locale’s full month name. | |
%c | Locale’s appropriate date and time representation. | |
%d | Day of the month as a decimal number [01,31]. | |
%H | Hour (24-hour clock) as a decimal number [00,23]. | |
%I | Hour (12-hour clock) as a decimal number [01,12]. | |
%j | Day of the year as a decimal number [001,366]. | |
%m | Month as a decimal number [01,12]. | |
%M | Minute as a decimal number [00,59]. | |
%p | Locale’s equivalent of either AM or PM. | (1) |
%S | Second as a decimal number [00,61]. | (2) |
%U | Week number of the year (Sunday as the first day of the week) as a decimal number [00,53]. All days in a new year preceding the first Sunday are considered to be in week 0. | (3) |
%w | Weekday as a decimal number [0(Sunday),6]. | |
%W | Week number of the year (Monday as the first day of the week) as a decimal number [00,53]. All days in a new year preceding the first Monday are considered to be in week 0. | (3) |
%x | Locale’s appropriate date representation. | |
%X | Locale’s appropriate time representation. | |
%y | Year without century as a decimal number [00,99]. | |
%Y | Year with century as a decimal number. | |
%Z | Time zone name (no characters if no time zone exists). | |
%% | A literal ‘%’ character. |
time.strptime(string[,format])
将按照format格式化好的字符串转换为时间元组
一些简单的例子
>>> import datetime
>>> today = datetime.date.today()
>>> today
datetime.date(2015, 4, 18)
>>> today + datetime.timedelta(days=1)
datetime.date(2015, 4, 19)
>>> print today + datetime.timedelta(days=1)
2015-04-19
>>> today = datetime.datetime.today()
>>> today
datetime.datetime(2015, 4, 18, 12, 57, 40, 115000)
>>> import datetime,calendar
>>> lastFriday = datetime.date.today()
>>> oneday = datetime.timedelta(days=1)
>>> while lastFriday.weekday() != calendar.FRIDAY:
lastFriday -= oneday
>>> print lastFriday
2015-04-17
>>> print lastFriday.strftime('%A-%Y/%m/%d')
Friday-2015/04/17
-----------------第二种方法--------------------------
>>> today = datetime.date(2014,3,5)
>>> this_weekday = today.weekday()
>>> this_weekday
2
>>> delta_weekday = (this_weekday - calendar.FRIDAY) % 7
>>> last_friday = today - datetime.timedelta(days=delta_weekday)
>>> print last_friday
2014-02-28
def totalTimes(times):
td = datetime.timedelta(0)
duration = sum((datetime.timedelta(minutes=m,seconds=s) for m,s in times),td)
return duration
decimal.Decimal(string or int)–>返回一个decimal对象
一些例子:
>>> from decimal import *
>>> setcontext(ExtendedContext)
>>> Decimal(0)
Decimal('0')
>>> Decimal('1')
Decimal('1')
>>> Decimal('-.0123')
Decimal('-0.0123')
>>> Decimal(123456)
Decimal('123456')
>>> Decimal('123.45e12345678901234567890')
Decimal('1.2345E+12345678901234567892')
>>> Decimal('1.33') + Decimal('1.27')
Decimal('2.60')
>>> Decimal('12.34') + Decimal('3.87') - Decimal('18.41')
Decimal('-2.20')
>>> dig = Decimal(1)
>>> print dig / Decimal(3)
0.333333333
>>> getcontext().prec = 18
>>> print dig / Decimal(3)
0.333333333333333333
>>> print dig.sqrt()
1
>>> print Decimal(3).sqrt()
1.73205080756887729
>>> print Decimal(3) ** 123
4.85192780976896427E+58
>>> inf = Decimal(1) / Decimal(0)
>>> print inf
Infinity
>>> neginf = Decimal(-1) / Decimal(0)
>>> print neginf
-Infinity
>>> print neginf + inf
NaN
>>> print neginf * inf
-Infinity
>>> print dig / 0
Infinity
>>> getcontext().traps[DivisionByZero] = 1
>>> print dig / 0
Traceback (most recent call last):
...
...
...
DivisionByZero: x / 0
>>> c = Context()
>>> c.traps[InvalidOperation] = 0
>>> print c.flags[InvalidOperation]
0
>>> c.divide(Decimal(0), Decimal(0))
Decimal('NaN')
>>> c.traps[InvalidOperation] = 1
>>> print c.flags[InvalidOperation]
1
>>> c.flags[InvalidOperation] = 0
>>> print c.flags[InvalidOperation]
0
>>> print c.divide(Decimal(0), Decimal(0))
Traceback (most recent call last):
...
...
...
InvalidOperation: 0 / 0
>>> print c.flags[InvalidOperation]
1
>>> c.flags[InvalidOperation] = 0
>>> c.traps[InvalidOperation] = 0
>>> print c.divide(Decimal(0), Decimal(0))
NaN
>>> print c.flags[InvalidOperation]
1
python中给变量赋值实际上是变量对值(对象)的引用,当通过一个变量修改了值(对象),也会影响到其它引用了相同值(对象)的变量。例如:
>>> a = [1, 2, 3, 4]
>>> b = a
>>> b[2] = 4
>>> a,b
([1, 2, 4, 4], [1, 2, 4, 4])
a,b都引用了同一个列表值,当变量b修改了列表值,因为变量a引用同一个列表,所以变量a会受到影响。
如果想要拷贝一个值(对象),可以考虑使用copy模块。
例子:
>>> a = [[1,2,3],[12,32],[21,32,45]]
>>> import copy
>>> b = copy.copy(a)
>>> b
[[1, 2, 3], [12, 32], [21, 32, 45]]
>>> b[0] = [2]
>>> a,b
([[1, 2, 3], [12, 32], [21, 32, 45]], [[2], [12, 32], [21, 32, 45]])
>>> b[1][0] = 23
>>> a,b
([[1, 2, 3], [23, 32], [21, 32, 45]], [[2], [23, 32], [21, 32, 45]])
注意到当执行b[1][0] = 23后,变量a也受到了影响。这是因为copy.copy()只是浅层拷贝,对于嵌套的值而言,还是简单的引用。要想嵌套的拷贝一个值(对象),应该使用copy.deepcopy()。
另外实现拷贝的方法还有
>>> a = [1,2,3,4]
>>> b = list(a)
>>> a,b
([1, 2, 3, 4], [1, 2, 3, 4])
>>> a[0] = 2
>>> a,b
([2, 2, 3, 4], [1, 2, 3, 4])
注意:
>>> l = [[]] * 10
>>> l
[[], [], [], [], [], [], [], [], [], []]
>>> l[0].append(2)
>>> l
[[2], [2], [2], [2], [2], [2], [2], [2], [2], [2]]
之所以会出现执行l[0].append(2)后,所有嵌套列表都追加了2的情况,是因为[[]] * 10
是浅层拷贝,每个嵌套列表实际上都是引用同一个值,修改任意一个嵌套列表都会影响其它的嵌套列表。
列表推导是一次生成所有值,而生成器表达式则是每次生成一个值,节省内存。
def list_get(L, index, v=None):
if -len(L) <= index < len(L):
return L[index]
else:
return v
# or
def list_get(L, index, v=None):
try:
return L[index]
except IndexError:
return v
第一个函数相对第二个来所,效率更快。
#推荐做法
for index, item in enumerate(seq):
process(index)
process(item)
#而不是
for i in range(len(seq)):
process(seq[i])
#递归版本
def list_or_tuple(seq):
return True if isinstance(seq,(list,tuple)) else False
def nonstring_iterable(seq):
try:
iter(seq)
except TypeError:
return False
else:
return not isinstance(seq,basestring)
def flatten(seq, to_expand=list_or_tuple):
for item in seq:
if to_expand(item):
for item in flatten(item, to_expand=list_or_tuple):
yield item
else:
yield item
#非递归版本
def flatten(seq, to_expand=list_or_tuple):
iterators = [iter(seq)] #将seq转换为迭代器对象,可以保存遍历的状态
while iterators:
for item in iterators[-1]:
if to_expand(item):
iterators.append(iter(item))
break
else:
yield item
else:
iterators.pop()
#列表推导
[[row[col] for row in matrix] for col in range(len(matrix[0]))]
#map,zip
map(list, zip(*matrix))
创建新字典
dict(**kwargs)
dict(zip(key_seq, val_seq))
update(…)
D.update([E, ]**F) -> None. Update D from dict/iterable E and F.
If E present and has a .keys() method, does: for k in E: D[k] = E[k]
If E present and lacks .keys() method, does: for (k, v) in E: D[k] = v
In either case, this is followed by: for k in F: D[k] = F[k]
#第一种方法
dict(zip(keys_vals[::2], keys_vals[1::2]))
#第二种方法
def pairwise(keys_vals):
next = iter(keys_vals).next
while True:
yield next(), next()
def dictFromSeq(seq):
return dict(pairwise(seq))
python中排序方法称为DSU(Decorate-sort-Undecorate)
key_vals = [(k, v) for k, v in adict.items()] #装饰
key_vals.sort() #排序
cmp可以比较两个单一元素(int,float),也可以比较可迭代对象。比较过程的代码类似于:
while i < len(a) and i < len(b):
res = cmp(a[i], b[i])
if res:
return res
i += 1
return cmp(len(a), len(b))
优先队列
heapq.heappop()
heapq.heappush()
可用Queue.PriorityQueue代替
简单粗暴的方法
alist.sort()
alist[:n]
使用heapq模块
heapq.nsmallest(n, alist)
def isorted(data):
data = list(data) #这里不仅将data转换为list,而且还获得data的一份拷贝
heapq.heapify(data) #将data初始化为heap
while data:
yield heapq.heappop(data)
模块bisect
bisect.bisect(a, x[, lo[, hi]])–>index
Return the index where to insert item x in list a, assuming a is sorted.
The return value i is such that all e in a[:i] have e <= x, and all e in a[i:] have e > x. So if x already appears in the list, i points just
beyond the rightmost x already there
具体信息可查看python doc
当列表长度较小,且元素易于比较(如int, float,string)时,可以采用下面这种先排序再取值的方法
data.sort()
data[n]
当列表长度非常大,而且元素比较开销较大,那么上面这种先排序再取值的方法效率偏低。
def select(data, n):
data = list(data)
pivot_count = 0
under = []
over = []
uappend = under.append #优化技巧
oappend = over.append
while True:
pivot = random.choice(data)
for item in data:
if item < pivot:
uappend(item)
elif item > pivot:
oappend(item)
else:
pivot_count += 1
if n < len(under):
data = under
elif n < len(under) + pivot_count:
return pivot
else:
data = over
n -= len(under) + pivot_count
def finditer(text, pattern):
pos = -1
while True:
pos = text.find(pattern, pos + 1)
if pos < 0: break
yield pos