Python数据结构(字符串、列表、元组、字典、set集合)
1、一切皆对象
PyChram如何快速查找系统函数的源码内容
注:系统函数的实现代码查看builtins.py(包含列表、元组、字典)
对于Python,一切事物都是对象,对象基于类创建
所以,以下这些值都是对象: "wupeiqi"、38、['北京', '上海', '深圳'],并且是根据不同的类生成的对象。
(图转自大牛)
2、字符串
2.1 字符串概述
在Python有各种各样的string操作函数。在历史上string类在python中经历了一段轮回的历史。在最开始的时候,python有一个 专门的string的module,要使用string的方法要先import,但后来由于众多的python使用者的建议,从python2.0开始, string方法改为用S.method()的形式调用,只要S是一个字符串对象就可以这样使用,而不用import。同时为了保持向后兼容,现在的 python中仍然保留了一个string的module,其中定义的方法与S.method()是相同的,这些方法都最后都指向了用S.method ()调用的函数。要注意,S.method()能调用的方法比string的module中的多,比如isdigit()、istitle()等就只能用 S.method()的方式调用。
对一个字符串对象,首先想到的操作可能就是计算它有多少个字符组成,很容易想到用S.len(),但这是
错的,应该是len(S)。因为len()是内置函数,包括在__builtin__模块中。python不把len()包含在string类型中,乍看
起来好像有点不可理解,其实一切有其合理的逻辑在里头。len()不仅可以计算字符串中的字符数,还可以计算list的成员数,tuple的成员数等等,
因此单单把len()算在string里是不合适,因此一是可以把len()作为通用函数,用重载实现对不同类型的操作,还有就是可以在每种有len()
运算的类型中都要包含一个len()函数。
python选择的是第一种解决办法。类似的还有str(arg)函数,它把arg用string类型表示出来。
2.2 字符串功能列表
class str(basestring): """ str(object='') -> string Return a nice string representation of the object. If the argument is a string, the return value is the same object. """ def capitalize(self): """ 首字母变大写 """ """ S.capitalize() -> string Return a copy of the string S with only its first character capitalized. """ return "" def center(self, width, fillchar=None): """ 内容居中,width:总长度;fillchar:空白处填充内容,默认无 """ """ S.center(width[, fillchar]) -> string Return S centered in a string of length width. Padding is done using the specified fill character (default is a space) """ return "" def count(self, sub, start=None, end=None): """ 子序列个数 """ """ S.count(sub[, start[, end]]) -> int Return the number of non-overlapping occurrences of substring sub in string S[start:end]. Optional arguments start and end are interpreted as in slice notation. """ return 0 def decode(self, encoding=None, errors=None): """ 解码 """ """ S.decode([encoding[,errors]]) -> object Decodes S using the codec registered for encoding. encoding defaults to the default encoding. errors may be given to set a different error handling scheme. Default is 'strict' meaning that encoding errors raise a UnicodeDecodeError. Other possible values are 'ignore' and 'replace' as well as any other name registered with codecs.register_error that is able to handle UnicodeDecodeErrors. """ return object() def encode(self, encoding=None, errors=None): """ 编码,针对unicode """ """ S.encode([encoding[,errors]]) -> object Encodes S using the codec registered for encoding. encoding defaults to the default encoding. errors may be given to set a different error handling scheme. Default is 'strict' meaning that encoding errors raise a UnicodeEncodeError. Other possible values are 'ignore', 'replace' and 'xmlcharrefreplace' as well as any other name registered with codecs.register_error that is able to handle UnicodeEncodeErrors. """ return object() def endswith(self, suffix, start=None, end=None): """ 是否以 xxx 结束 """ """ S.endswith(suffix[, start[, end]]) -> bool Return True if S ends with the specified suffix, False otherwise. With optional start, test S beginning at that position. With optional end, stop comparing S at that position. suffix can also be a tuple of strings to try. """ return False def expandtabs(self, tabsize=None): """ 将tab转换成空格,默认一个tab转换成8个空格 """ """ S.expandtabs([tabsize]) -> string Return a copy of S where all tab characters are expanded using spaces. If tabsize is not given, a tab size of 8 characters is assumed. """ return "" def find(self, sub, start=None, end=None): """ 寻找子序列位置,如果没找到,返回 -1 """ """ S.find(sub [,start [,end]]) -> int Return the lowest index in S where substring sub is found, such that sub is contained within S[start:end]. Optional arguments start and end are interpreted as in slice notation. Return -1 on failure. """ return 0 def format(*args, **kwargs): # known special case of str.format """ 字符串格式化,动态参数,将函数式编程时细说 """ """ S.format(*args, **kwargs) -> string Return a formatted version of S, using substitutions from args and kwargs. The substitutions are identified by braces ('{' and '}'). """ pass def index(self, sub, start=None, end=None): """ 子序列位置,如果没找到,报错 """ S.index(sub [,start [,end]]) -> int Like S.find() but raise ValueError when the substring is not found. """ return 0 def isalnum(self): """ 是否是字母和数字 """ """ S.isalnum() -> bool Return True if all characters in S are alphanumeric and there is at least one character in S, False otherwise. """ return False def isalpha(self): """ 是否是字母 """ """ S.isalpha() -> bool Return True if all characters in S are alphabetic and there is at least one character in S, False otherwise. """ return False def isdigit(self): """ 是否是数字 """ """ S.isdigit() -> bool Return True if all characters in S are digits and there is at least one character in S, False otherwise. """ return False def islower(self): """ 是否小写 """ """ S.islower() -> bool Return True if all cased characters in S are lowercase and there is at least one cased character in S, False otherwise. """ return False def isspace(self): """ S.isspace() -> bool Return True if all characters in S are whitespace and there is at least one character in S, False otherwise. """ return False def istitle(self): """ S.istitle() -> bool Return True if S is a titlecased string and there is at least one character in S, i.e. uppercase characters may only follow uncased characters and lowercase characters only cased ones. Return False otherwise. """ return False def isupper(self): """ S.isupper() -> bool Return True if all cased characters in S are uppercase and there is at least one cased character in S, False otherwise. """ return False def join(self, iterable): """ 连接 """ """ S.join(iterable) -> string Return a string which is the concatenation of the strings in the iterable. The separator between elements is S. """ return "" def ljust(self, width, fillchar=None): """ 内容左对齐,右侧填充 """ """ S.ljust(width[, fillchar]) -> string Return S left-justified in a string of length width. Padding is done using the specified fill character (default is a space). """ return "" def lower(self): """ 变小写 """ """ S.lower() -> string Return a copy of the string S converted to lowercase. """ return "" def lstrip(self, chars=None): """ 移除左侧空白 """ """ S.lstrip([chars]) -> string or unicode Return a copy of the string S with leading whitespace removed. If chars is given and not None, remove characters in chars instead. If chars is unicode, S will be converted to unicode before stripping """ return "" def partition(self, sep): """ 分割,前,中,后三部分 """ """ S.partition(sep) -> (head, sep, tail) Search for the separator sep in S, and return the part before it, the separator itself, and the part after it. If the separator is not found, return S and two empty strings. """ pass def replace(self, old, new, count=None): """ 替换 """ """ S.replace(old, new[, count]) -> string Return a copy of string S with all occurrences of substring old replaced by new. If the optional argument count is given, only the first count occurrences are replaced. """ return "" def rfind(self, sub, start=None, end=None): """ S.rfind(sub [,start [,end]]) -> int Return the highest index in S where substring sub is found, such that sub is contained within S[start:end]. Optional arguments start and end are interpreted as in slice notation. Return -1 on failure. """ return 0 def rindex(self, sub, start=None, end=None): """ S.rindex(sub [,start [,end]]) -> int Like S.rfind() but raise ValueError when the substring is not found. """ return 0 def rjust(self, width, fillchar=None): """ S.rjust(width[, fillchar]) -> string Return S right-justified in a string of length width. Padding is done using the specified fill character (default is a space) """ return "" def rpartition(self, sep): """ S.rpartition(sep) -> (head, sep, tail) Search for the separator sep in S, starting at the end of S, and return the part before it, the separator itself, and the part after it. If the separator is not found, return two empty strings and S. """ pass def rsplit(self, sep=None, maxsplit=None): """ S.rsplit([sep [,maxsplit]]) -> list of strings Return a list of the words in the string S, using sep as the delimiter string, starting at the end of the string and working to the front. If maxsplit is given, at most maxsplit splits are done. If sep is not specified or is None, any whitespace string is a separator. """ return [] def rstrip(self, chars=None): """ S.rstrip([chars]) -> string or unicode Return a copy of the string S with trailing whitespace removed. If chars is given and not None, remove characters in chars instead. If chars is unicode, S will be converted to unicode before stripping """ return "" def split(self, sep=None, maxsplit=None): """ 分割, maxsplit最多分割几次 """ """ S.split([sep [,maxsplit]]) -> list of strings Return a list of the words in the string S, using sep as the delimiter string. If maxsplit is given, at most maxsplit splits are done. If sep is not specified or is None, any whitespace string is a separator and empty strings are removed from the result. """ return [] def splitlines(self, keepends=False): """ 根据换行分割 """ """ S.splitlines(keepends=False) -> list of strings Return a list of the lines in S, breaking at line boundaries. Line breaks are not included in the resulting list unless keepends is given and true. """ return [] def startswith(self, prefix, start=None, end=None): """ 是否起始 """ """ S.startswith(prefix[, start[, end]]) -> bool Return True if S starts with the specified prefix, False otherwise. With optional start, test S beginning at that position. With optional end, stop comparing S at that position. prefix can also be a tuple of strings to try. """ return False def strip(self, chars=None): """ 移除两段空白 """ """ S.strip([chars]) -> string or unicode Return a copy of the string S with leading and trailing whitespace removed. If chars is given and not None, remove characters in chars instead. If chars is unicode, S will be converted to unicode before stripping """ return "" def swapcase(self): """ 大写变小写,小写变大写 """ """ S.swapcase() -> string Return a copy of the string S with uppercase characters converted to lowercase and vice versa. """ return "" def title(self): """ S.title() -> string Return a titlecased version of S, i.e. words start with uppercase characters, all remaining cased characters have lowercase. """ return "" def translate(self, table, deletechars=None): """ 转换,需要先做一个对应表,最后一个表示删除字符集合 intab = "aeiou" outtab = "12345" trantab = maketrans(intab, outtab) str = "this is string example....wow!!!" print str.translate(trantab, 'xm') """ """ S.translate(table [,deletechars]) -> string Return a copy of the string S, where all characters occurring in the optional argument deletechars are removed, and the remaining characters have been mapped through the given translation table, which must be a string of length 256 or None. If the table argument is None, no translation is applied and the operation simply removes the characters in deletechars. """ return "" def upper(self): """ S.upper() -> string Return a copy of the string S converted to uppercase. """ return "" def zfill(self, width): """方法返回指定长度的字符串,原字符串右对齐,前面填充0。""" """ S.zfill(width) -> string Pad a numeric string S with zeros on the left, to fill a field of the specified width. The string S is never truncated. """ return "" def _formatter_field_name_split(self, *args, **kwargs): # real signature unknown pass def _formatter_parser(self, *args, **kwargs): # real signature unknown pass def __add__(self, y): """ x.__add__(y) <==> x+y """ pass def __contains__(self, y): """ x.__contains__(y) <==> y in x """ pass def __eq__(self, y): """ x.__eq__(y) <==> x==y """ pass def __format__(self, format_spec): """ S.__format__(format_spec) -> string Return a formatted version of S as described by format_spec. """ return "" def __getattribute__(self, name): """ x.__getattribute__('name') <==> x.name """ pass def __getitem__(self, y): """ x.__getitem__(y) <==> x[y] """ pass def __getnewargs__(self, *args, **kwargs): # real signature unknown pass def __getslice__(self, i, j): """ x.__getslice__(i, j) <==> x[i:j] Use of negative indices is not supported. """ pass def __ge__(self, y): """ x.__ge__(y) <==> x>=y """ pass def __gt__(self, y): """ x.__gt__(y) <==> x>y """ pass def __hash__(self): """ x.__hash__() <==> hash(x) """ pass def __init__(self, string=''): # known special case of str.__init__ """ str(object='') -> string Return a nice string representation of the object. If the argument is a string, the return value is the same object. # (copied from class doc) """ pass def __len__(self): """ x.__len__() <==> len(x) """ pass def __le__(self, y): """ x.__le__(y) <==> x<=y """ pass def __lt__(self, y): """ x.__lt__(y) <==> x<y """ pass def __mod__(self, y): """ x.__mod__(y) <==> x%y """ pass def __mul__(self, n): """ x.__mul__(n) <==> x*n """ pass @staticmethod # known case of __new__ def __new__(S, *more): """ T.__new__(S, ...) -> a new object with type S, a subtype of T """ pass def __ne__(self, y): """ x.__ne__(y) <==> x!=y """ pass def __repr__(self): """ x.__repr__() <==> repr(x) """ pass def __rmod__(self, y): """ x.__rmod__(y) <==> y%x """ pass def __rmul__(self, n): """ x.__rmul__(n) <==> n*x """ pass def __sizeof__(self): """ S.__sizeof__() -> size of S in memory, in bytes """ pass def __str__(self): """ x.__str__() <==> str(x) """ pass str str
2.3 应用案例
参考资料:http://www.runoob.com/python/python-strings.html
2.3.1 去空格及特殊符号
>>> a = " your are a boy. " >>> >>> a ' your are a boy. ' >>> a.strip() # 两边去空格 'your are a boy.' >>> a.lstrip() # 右边去空格 'your are a boy. ' >>> a.rstrip() # 左边去空格 ' your are a boy.'
2.3.2 字符串大小写变换
格式:
S.lower()
S.upper()
S.swapcase()
S.capitalize()
S.title()
案例:
>>> str1 = "strcpy S" >>> str1.capitalize() # 首字母大写 'Strcpy s' >>> str1.lower() # 所有字母小写 'strcpy s' >>> str1.upper() # 所有字母大写 'STRCPY S' >>> str1.title() # 只有首字母大写,其余为小写,模块中没有这个方法 'Strcpy S' >>> str1.swapcase() # 字母大小写互换 'STRCPY s'
2.3.3 字符对齐
格式:
S.ljust(width,[fillchar])
S.rjust(width,[fillchar])
S.center(width, [fillchar])
S.zfill(width)
案例:
>>> str1 = "sdfsderwerafdsf" >>> str1.ljust(20) # 输出width个字符,左对齐,不足部分用指定字符填充,默认的为空格 'sdfsderwerafdsf ' >>> str1.ljust(20,'-') # 指定填充字符 'sdfsderwerafdsf-----' >>> str1.rjust(20) # 同ljust,按照右对齐 ' sdfsderwerafdsf' >>> str1.rjust(20,'-') # 同ljust,按照右对齐,指定填充字符 '-----sdfsderwerafdsf' >>> str1.center(20,'-') # 中间对齐 '--sdfsderwerafdsf---' >>> str1.zfill(20) # 把指定字符串变成width长,并在右对齐,不足部分用0补足 '00000sdfsderwerafdsf'
2.3.4 字符串搜索和替换
格式: S.find(substr, [start, [end]]) # 返回S中出现substr的第一个字母的标号,如果S中没有substr则返回-1。start和end作用就相当于在S[start:end]中搜索 S.index(substr, [start, [end]]) # 与find()相同,只是在S中没有substr时,会返回一个运行时错误 S.rfind(substr, [start, [end]]) # 返回S中最后出现的substr的第一个字母的标号,如果S中没有substr则返回-1,也就是说从右边算起的第一次出现的substr的首字母标号 S.rindex(substr, [start, [end]]) S.count(substr, [start, [end]]) # 计算substr在S中出现的次数 S.replace(oldstr, newstr, [count])# 把S中的oldstar替换为newstr,count为替换次数。这是替换的通用形式,还有一些函数进行特殊字符的替换 S.strip([chars]) # 把S中前后chars中有的字符全部去掉,可以理解为把S前后chars替换为None S.lstrip([chars]) S.rstrip([chars]) S.expandtabs([tabsize]) # 把S中的tab字符替换没空格,每个tab替换为tabsize个空格,默认是8个 案例: >>> str1 = "sdfsderwerafsdsf" >>> str1.find("fs") 2 >>> str1.find("fs",4) 11 >>> str1.index("fs") 2 >>> str1.rfind("fs") 11 >>> str1.rindex("fs") 11 >>> str1.count("fs") 2 >>> str1.replace("fs","ab") 'sdabderweraabdsf' >>> str1.replace("fs","ab",1) 'sdabderwerafsdsf' >>> str1.strip("fs") # 不是整体过滤fs字符,过滤f,s中两个的任何一个,匹配字符串的前后的第一个字符 'dfsderwerafsd' >>> str1.strip("f") >>> str1.lstrip("f") 'sdfsderwerafsdsf' >>> str1.rstrip("f") 'sdfsderwerafsds' >>> str = "this is\tstring example....wow!!!"; >>> >>> print("Original string: " + str) Original string: this is string example....wow!!! >>> print("Defualt exapanded tab: " + str.expandtabs()) Defualt exapanded tab: this is string example....wow!!! >>> print("Double exapanded tab: " + str.expandtabs(16)) Double exapanded tab: this is string example....wow!!! 'sdfsderwerafsds'
2.3.5 字符串的分割和组合
S.split([sep, [maxsplit]]) # 以sep为分隔符,把S分成一个list。maxsplit表示分割的次数。默认的分割符为空白字符 S.rsplit([sep, [maxsplit]]) S.splitlines([keepends]) # 把S按照行分割符分为一个list,keepends是一个bool值,如果为真每行后而会保留行分割符。 S.join(seq) # join将容器对象拆分并以指定的字符将列表内的元素(element)连接起来,返回字符串(注:容器对象内的元素须为字符类型) >>> str1 = "sdfsderwerafsdsf" >>> str1.split("s") ['', 'df', 'derweraf', 'd', 'f'] >>> str1.split("s",1) ['', 'dfsderwerafsdsf'] # 案例1 >>> str1 'sdfsderwerafsdsf' >>> str1.join("ccc") 'csdfsderwerafsdsfcsdfsderwerafsdsfc' # 案例2 >>> a = ['no','pain','no','gain'] >>> '_ '.join(a) 'no_pain_no_gain' # 容器对象内的元素须为字符类型 >>> b = ['I','am','no',1] >>> '_'.join(b) Traceback (most recent call last): File "<pyshell#32>", line 1, in <module> '_'.join(b) TypeError: sequence item 3: expected string, int found # dict是以Key值作连接 dict的无序性,使元素随机连接。set 同理 >>> L = {'p':'P','y':'Y','t':'T','h':'H','o':'O','n':'N'} >>> '_'.join(L) 'h_o_n_p_t_y'
2.3.6 字符串的mapping
S.maketrans(from, to) # 返回一个256个字符组成的翻译表,其中from中的字符被一一对应地转换成to,所以from和to必须是等长的。 S.translate(table[,deletechars])# 使用上面的函数产后的翻译表,把S进行翻译,并把deletechars中有的字符删掉。需要注意的是,如果S为unicode字符串,那么就不支持 deletechars参数,可以使用把某个字符翻译为None的方式实现相同的功能。此外还可以使用codecs模块的功能来创建更加功能强大的翻译表。
2.3.7 解码与编码
S.encode([encoding,[errors]]) # 以 encoding 指定的编码格式编码 string,如果出错默认报一个ValueError 的异常,除非 errors 指定的是'ignore'或者'replace' S.decode([encoding,[errors]]) # 字符串的测试函数,这一类函数在string模块中没有,这些函数返回的都是bool值
2.3.8 字符串的测试函数
格式: S.startwith(prefix[,start[,end]]) # 是否以prefix开头 S.endwith(suffix[,start[,end]]) # 以suffix结尾 S.isalnum() # 是否全是字母和数字,并至少有一个字符 S.isalpha() # 是否全是字母,并至少有一个字符 S.isdigit() # 是否全是数字,并至少有一个字符 S.isspace() # 是否全是空白字符,并至少有一个字符 S.islower() # S中的字母是否全是小写 S.isupper() # S中的字母是否便是大写 S.istitle() # S是否是首字母大写的 注:这一类函数在string模块中没有,这些函数返回的都是bool值 案例: >>> str1 = "sdfsderwerafsdsf" >>> str1.startswith("s") True >>> str1.endswith("f") True >>> str1.endswith("c") False # 实际应用案例 # 案例1:根据后缀名判断文件类型 filename = "ftp.exe" if (filename.endswith(".exe")): print("这是一个exe执行文件") else: print("这不是一个exe执行文件") # 案例2:根据后缀名判断文件是否为图片 fileName1='pic.jpg' # if fileName1.endswith('.gif') or fileName1.endswith('.jpg') or fileName1.endswith('.png'): if fileName1.endswith((".gif", "jpg", ".png")): # 与上一句等效 print('这是一张图片') else: print('这不是一张图片') # 案例3:结合os模块查找当前目录下的某个类型的文件 import os items = os.listdir(".") newlist = [] for name in items: if name.endswith(".py"): newlist.append(name) print(newlist) >>> str1.isalnum() True >>> str1.isalpha() True >>> str1.isdigit() False >>> str1.isspace() False >>> str1.islower() True >>> str1.isupper() False >>> str1.istitle() False:
2.3.9 汉语转拼音
资料:http://pypinyin.readthedocs.io/en/latest/
应用案例:
pypinyin安装: pip install pypinyin >>> from pypinyin import pinyin,lazy_pinyin >>> import pypinyin >>> a = "杩栋胜" >>> lazy_pinyin(a) ['ma', 'dong', 'sheng']
注:
再强调一次,字符串对象是不可改变的,也就是说在Python创建一个字符串后,你不能把这个字符中的某一部分改变。任何上面的函数改变了字符串后,都会返回一个新的字符串,原字串并没有变。其实这也是有变通的办法的,可以用S=list(S)这个函数把S变为由单个字符为成员的list,这样的话就可以使用S[3]='a'的方式改变值,然后再使用S=" ".join(S)还原成字符串
2.4 字符串格式化
目前Python字符串的格式化有两种方法:百分号方式、format方式(百分号方式相对古老,format相对先进,目前两者并存)
2.4.1 百分号方式
语法格式:%[(name)][flags][width].[precision]typecode
(name) 可选,用于选择指定的key
flags 可选,可供选择的值有:
+ 右对齐;正数前加正好,负数前加负号;
- 左对齐;正数前无符号,负数前加负号;
空格 右对齐;正数前加空格,负数前加负号;
0 右对齐;正数前无符号,负数前加负号;用0填充空白处
width 可选,占有宽度
.precision 可选,小数点后保留的位数
typecode 必选
s,获取传入对象的__str__方法的返回值,并将其格式化到指定位置
r,获取传入对象的__repr__方法的返回值,并将其格式化到指定位置
c,整数:将数字转换成其unicode对应的值,10进制范围为 0 <= i <= 1114111(py27则只支持0-255);字符:将字符添加到指定位置
o,将整数转换成 八 进制表示,并将其格式化到指定位置
x,将整数转换成十六进制表示,并将其格式化到指定位置
d,将整数、浮点数转换成 十 进制表示,并将其格式化到指定位置
e,将整数、浮点数转换成科学计数法,并将其格式化到指定位置(小写e)
E,将整数、浮点数转换成科学计数法,并将其格式化到指定位置(大写E)
f, 将整数、浮点数转换成浮点数表示,并将其格式化到指定位置(默认保留小数点后6位)
F,同上
g,自动调整将整数、浮点数转换成 浮点型或科学计数法表示(超过6位数用科学计数法),并将其格式化到指定位置(如果是科学计数则是e;)
G,自动调整将整数、浮点数转换成 浮点型或科学计数法表示(超过6位数用科学计数法),并将其格式化到指定位置(如果是科学计数则是E;)
%,当字符串中存在格式化标志时,需要用 %%表示一个百分号
注:Python中百分号格式化是不存在自动将整数转换成二进制表示的方式
常用的格式化练习:
>>> st = "I am a %s!" % "teacher" >>> print(st) I am a teacher! >>> >>> st = "I am a %20s!" % "teacher" # teacher 预留20个字符宽度,默认是右对齐 >>> print(st) I am a teacher! >>> >>> st = "I am a %+20s!" % "teacher" # teacher 预留20个字符宽度,指定右对齐 >>> print(st) I am a teacher! >>> >>> st = "I am a %-20s!" % "teacher" # teacher 预留20个字符宽度,指定左对齐 >>> print(st) I am a teacher ! >>> >>> st = "I am %s age %d" % ("teacher", 18) # 接受不同的数据类型 >>> print(st) I am teacher age 18 >>> >>> st = "I am %(name)s age %(age)d" % {"name": "teacher", "age": 18} # 使用变量传递参数 >>> print(st) I am teacher age 18 >>> >>> st = "percent %.2f" % 99.97623 # 保留两位小数 >>> print(st) percent 99.98 >>> >>> st = "I am %(pp).2f" % {"pp": 123.425556, } # 使用变量传递参数,保留两位小 数 >>> print(st) I am 123.43 >>> >>> st = "I am %.2f %%" % 123.425556 # 注意%% >>> print(st) I am 123.43 % >>>
2.4.2 format方式
[[fill]align][sign][#][0][width][,][.precision][type]
fill 【可选】空白处填充的字符
align 【可选】对齐方式(需配合width使用)
< 内容左对齐
> 内容右对齐(默认)
= 内容右对齐,将符号放置在填充字符的左侧,且只对数字类型有效。 即使:符号+填充物+数字
^ 内容居中
sign 【可选】有无符号数字
+ 正号加正,负号加负;
- 正号不变,负号加负;
空格 正号空格,负号加负;
# 【可选】对于二进制、八进制、十六进制,如果加上#,会显示 0b/0o/0x,否则不显示
, 【可选】为数字添加分隔符,如:1,000,000
width 【可选】格式化位所占宽度
.precision 【可选】小数位保留精度
type 【可选】格式化类型
传入"字符串类型"的参数
s,格式化字符串类型数据
空白,未指定类型,则默认是None,同s
传入"整数类型"的参数
b,将10进制整数自动转换成2进制表示然后格式化
c,将10进制整数自动转换为其对应的unicode字符
d,十进制整数
o,将10进制整数自动转换成8进制表示然后格式化;
x,将10进制整数自动转换成16进制表示然后格式化(小写x)
X,将10进制整数自动转换成16进制表示然后格式化(大写X)
传入"浮点型或小数类型"的参数
e, 转换为科学计数法(小写e)表示,然后格式化;
E, 转换为科学计数法(大写E)表示,然后格式化;
f , 转换为浮点型(默认小数点后保留6位)表示,然后格式化;
F, 转换为浮点型(默认小数点后保留6位)表示,然后格式化;
g, 自动在e和f中切换
G, 自动在E和F中切换
%,显示百分比(默认显示小数点后6位)
>>> # 比百分号格式化功能强大的地方 ... tpl = "I am {}, age {}, {}".format("seven", 29, "alex") >>> print(tpl) I am seven, age 29, alex >>> >>> tpl = "I am {}, age {}, {}".format(*["seven", 29, "alex", ]) >>> print(tpl) I am seven, age 29, alex >>> >>> tpl = "I am {0}, age {1}, really {0}".format("seven", 29,) >>> print(tpl) I am seven, age 29, really seven >>> >>> tpl = "I am {0}, age {1}, really {0}".format(*["seven", 29, ]) >>> print(tpl) I am seven, age 29, really seven >>> >>> tpl = "I am {name}, age {age}, really {name}".format(name="seven", age=29) >>> print(tpl) I am seven, age 29, really seven >>> >>> tpl = "I am {name}, age {age}, really {name}".format(**{"name": "seven", "ag e": 29}) >>> print(tpl) I am seven, age 29, really seven >>> >>> tpl = "I am {0[0]}, age {0[1]}, really {0[2]}".format([1, 2, 3, ], [11, 22, 33, ]) >>> print(tpl) I am 1, age 2, really 3 >>> >>> # 以下案例都开始指定接收参数的格式 ... >>> tpl = "I am {:s}, age {:d}, really {:f}".format("seven", 29, 922.002) >>> print(tpl) I am seven, age 29, really 922.002000 >>> >>> >>> tpl = "I am {:s}, age {:d}".format(*["seven", 29, ]) >>> print(tpl) I am seven, age 29 >>> >>> tpl = "I am {name:s}, age {age:d}".format(name="seven", age=29) >>> print(tpl) I am seven, age 29 >>> >>> tpl = "I am {name:s}, age {age:d}".format(**{"name": "seven", "age": 29}) >>> print(tpl) I am seven, age 29 >>> >>> tpl = "numbers: 二进制:{:b}, 八进制:{:o}, 十进制:{:d}, 十六进制:{:x}, 十六进制:{:X}, 转为百分比:{:%}".format(15, 15, 15, 15, 15, 15.123232, ) >>> print(tpl) numbers: 二进制:1111, 八进制:17, 十进制:15, 十六进制:f, 十六进制:F, 转为百分比:1512.323200% >>> >>> tpl = "numbers: 二进制:{0:b}, 八进制:{0:o}, 十进制:{0:d}, 十六进制:{0:x}, 十六进制:{0:X}, 转为百分比:{0:%}".format(15) >>> print(tpl) numbers: 二进制:1111, 八进制:17, 十进制:15, 十六进制:f, 十六进制:F, 转为百分比:1500.000000% >>> >>> tpl = "numbers: 二进制:{num:b}, 八进制:{num:o}, 十进制:{num:d}, 十六进制:{num:x}, 十六进制:{num:X}, 转为百分比:{num:%}".format(num=15) >>> print(tpl) numbers: 二进制:1111, 八进制:17, 十进制:15, 十六进制:f, 十六进制:F, 转为百分比:1500.000000%
2.4.3 format比百分号格式优势
可以居中显示
可以转二进制
百分号区别
自定义填充字符
3、列表
官网文档:http://python.usyiyi.cn/python_343/tutorial/datastructures.html#tuples-and-sequences
3.1 列表简介
列表---->数组(其他语言)
可以存储任何类型的其他内容,数字、字符串、字典等等
列组的索引由0开始
列表书写建议 正常: li = [11,22,33,44] 建议: li = [11,22,33,44,]
列表常见操作:索引、切片、追加、删除、长度、切片、循环、包含
Python 2.x append(x):添加一个元素到列表的末尾。相当于a[len(a):] = [x] count(x):返回列表中 x 出现的次数 精确查找不支持模糊查找 extend:将给定列表L中的所有元素附加到原列表a的末尾。相当于a[len(a):] = L index(x):返回列表中第一个值为 x 的元素的索引。如果没有这样的元素将会报错 insert(x):在给定位置插入一个元素。第一个参数是准备插入到其前面的那个元素的索引,所以 a.insert(0, x) 在列表的最前面插入 pop(x):删除列表中给定位置的元素并返回它。如果未指定索引,a.pop() 删除并返回列表中的最后一个元素 remove(x):删除列表中第一个值为 x 的元素。如果没有这样的元素将会报错 reverse(x):反转列表中的元素。相当于[::-1] sort:原地排序列表中的元素 Python 3.x 新增 clear:删除列表中所有的元素。相当于del a[:] copy:返回列表的一个浅拷贝。等同于a[:]
>>> li = ['alex','eric','rain']
>>> li.reverse() # 列表元素反向输出
>>> li
['rain', 'eric', 'alex']
>>> li[::-1]
['Tony', 'alex', 'eric', 'rain']
>>> name_list = ['alex','65brother','tenglan'] # 初始化一个列表 >>> type(name_list) # 确定类型 <type 'list'> >>> help(name_list) # 获取详细帮助信息 >>> dir(name_list) # 获取简单信息 [ .....省略,'append', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort'] >>> name_list.append("xiaolan") # 追加一个值 >>> name_list # 查看追加结果 ['alex', '65brother', 'tenglan', 'xiaolan'] >>> name_list.insert(0,"xiaolan") # 通过索引值插入内容 >>> name_list # 查看追加结果 ['xiaolan', 'alex', '65brother', 'tenglan', 'xiaolan'] >>> name_list.count("xiaolan") # 计算“xiaolei”值得总数 >>> name_list.index("65brother") # 查看某个值得索引值 >>> name_list[2] # 通过索引取值 '65brother' >>> name_list.remove("alex") # 移除扫描到的第一个alex值 >>> name_list ['xiaolan', '65brother', 'tenglan', 'xiaolan'] # 查看移除结果 >>> name_list.pop() # 移除最后一个值,并返回该值 'xiaolan' >>> name_list # 查看移除效果 ['xiaolan', '65brother', 'tenglan'] '''extend''' >>> a [1, 2, 3, 4, 6, 'a', 'b'] >>> b = ['c','d',4,24,6] >>> a + b # 两个列表合并 [1, 2, 3, 4, 6, 'a', 'b', 'c', 'd', 4, 24, 6] >>> a.extend(b) # 把b的内容扩展到a列表 >>> a [1, 2, 3, 4, 6, 'a', 'b', 'c', 'd', 4, 24, 6] >>> name = "Alex Li" >>> a.extend(name) # 把字符串的每个字母拆分扩展到a列表 >>> a [1, 2, 3, 4, 6, 'a', 'b', 'c', 'd', 4, 24, 6, 'A', 'l', 'e', 'x', ' ', 'L', 'i'] '''包含 ''' >>> a [1, 2, 3, 4, 6, 'a', 'b', 'c', 'd', 4, 24, 6, 'A', 'l', 'e', 'x', ' ', 'L', 'i'] >>> "A" in a # 字母A是否包含在列表a中 True >>> 24 in a # 数字24 是否包含在列表a中 True ''' 列表的各行打印''' >>> name_list = ['alex','65brother','tenglan'] >>> print(name_list[::2]) # [起始位置:结束位置:步长] ['alex', 'tenglan'] '''sort ''' sort Python 2.x(int,str按照ASCII排序) sort Python 3.x(int,str不能同时存在排序) ''' 切片''' name = ['alex','ccc',33,55] name[0] # 第一个 name[1] # 第二个 不知道列表中元素个数 如何取倒数第一个? name[-1] # 倒数第一个 name[0:2] # 一次取n个 取值 顾头不顾尾 name # 取所有值 name[:] # 取所有值 列表可以不断的切分 name[:6][2:5][0][1]
注:像insert, remove 或者 sort之类的方法只修改列表而没有返回值打印出来 -- 它们其实返回了默认值None ''' 深copy和浅copy 常见问题解答: 1)为什么要拷贝? 当进行修改时,想要保留原来的数据和修改后的数据 2)数字字符串和集合在修改时的差异?(深浅拷贝不同的终极原因) 在修改数据时: 数字字符串:在内存中新建一份数据 集合:修改内存中的同一份数据 3)对于集合,如何保留其修改前和修改后的数据? 在内存中拷贝一份 4)对于集合,如何拷贝其n层元素同时拷贝? 深拷贝 应用场景: 1)监控模板的copy应用 ''' ''' 浅copy案例 第一层copy 第二层copy ''' >>> name = ['alex',9,0,39,33,1245,'cc',34,'eeaaccdd',34,9,99,[8,"aa",9,20]] >>> name2 = name.copy() >>> name[0] = "Alex" >>> name[-1][0] = 88 >>> print(name) ['Alex', 9, 0, 39, 33, 1245, 'cc', 34, 'eeaaccdd', 34, 9, 99, [88, 'aa', 9, 20]] >>> print(name2) ['alex', 9, 0, 39, 33, 1245, 'cc', 34, 'eeaaccdd', 34, 9, 99, [88, 'aa', 9, 20]] ''' 深copy案例 第一层copy 第二层copy ''' >>> import copy >>> name = ['alex',9,0,39,33,1245,'cc',34,'eeaaccdd',34,9,99,[8,"aa",9,20]] >>> name2 = copy.deepcopy(name) >>> name[0] = "Alex" >>> name[-1][0] = 88 >>> print(name) ['Alex', 9, 0, 39, 33, 1245, 'cc', 34, 'eeaaccdd', 34, 9, 99, [88, 'aa', 9, 20]] >>> print(name2) ['alex', 9, 0, 39, 33, 1245, 'cc', 34, 'eeaaccdd', 34, 9, 99, [8, 'aa', 9, 20]]
3.2 列表应用场景
案例01:一千万条数据,有100条重复数据,要求删除这100条数据
>>> for count in range(name.count("some str")): ... name.remove("some str") ...
案例02:将列表作为堆栈使用
列表方法使得将列表当作堆栈非常容易,最先进入的元素最后一个取出(后进先出)。使用 append() 将元素添加到堆栈的顶部。使用不带索引的 pop() 从堆栈的顶部取出元素
>>> a [2, 5, 4, 3, 1] >>> a.append(6) >>> a.append(7) >>> a [2, 5, 4, 3, 1, 6, 7] >>> a.pop() 7 >>> a.pop() 6 >>> a [2, 5, 4, 3, 1]
案例03:将列表作为队列使用
也可以将列表当作队列使用,此时最先进入的元素第一个取出(先进先出);但是列表用作此目的效率不高。在列表的末尾添加和弹出元素非常快,但是在列表的开头插入或弹出元素却很慢 (因为所有的其他元素必须向左移一位)。
如果要实现一个队列,可以使用 collections.deque,它设计的目的就是在两端都能够快速添加和弹出元素
>>> from collections import deque >>> queue = deque([1,2,3,4]) # 一个队列,左边是头,右边是尾 先进先出 >>> queue.append(5) >>> queue deque([1, 2, 3, 4, 5]) >>> queue.append(6) >>> queue deque([1, 2, 3, 4, 5, 6]) >>> queue.popleft() 1 >>> queue deque([2, 3, 4, 5, 6])
3.3 del语句
del函数 删除内存中的值(适用范围:列表,变量、元组、字典等等)
>>> name_list = ['alex','65brother','tenglan','zhangsan','lisi'] >>> del name_list[0] >>> name_list ['65brother', 'tenglan', 'zhangsan', 'lisi'] >>> del name_list[2:3] # 清除子列表 >>> name_list ['65brother', 'tenglan', 'lisi'] >>> del name_list[:] # 清空列表 >>> name_list [] >>> del name_list # 清除变量 >>> name_list Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name 'name_list' is not defined
3.4 列表练习题
写一个列表,列表中包含本组所有成员的名字
往中间位置插入两个临组成员的名称
取出第3-8的人列表
删除第7个人
把刚才加入的两个临组的人一次性删除
把组长的名称加上组长备注
要求隔一个人打印一个
class list(object): """ list() -> new empty list list(iterable) -> new list initialized from iterable's items """ def append(self, p_object): # real signature unknown; restored from __doc__ """ L.append(object) -- append object to end """ pass def count(self, value): # real signature unknown; restored from __doc__ """ L.count(value) -> integer -- return number of occurrences of value """ return 0 def extend(self, iterable): # real signature unknown; restored from __doc__ """ L.extend(iterable) -- extend list by appending elements from the iterable """ pass def index(self, value, start=None, stop=None): # real signature unknown; restored from __doc__ """ L.index(value, [start, [stop]]) -> integer -- return first index of value. Raises ValueError if the value is not present. """ return 0 def insert(self, index, p_object): # real signature unknown; restored from __doc__ """ L.insert(index, object) -- insert object before index """ pass def pop(self, index=None): # real signature unknown; restored from __doc__ """ L.pop([index]) -> item -- remove and return item at index (default last). Raises IndexError if list is empty or index is out of range. """ pass def remove(self, value): # real signature unknown; restored from __doc__ """ L.remove(value) -- remove first occurrence of value. Raises ValueError if the value is not present. """ pass def reverse(self): # real signature unknown; restored from __doc__ """ L.reverse() -- reverse *IN PLACE* """ pass def sort(self, cmp=None, key=None, reverse=False): # real signature unknown; restored from __doc__ """ L.sort(cmp=None, key=None, reverse=False) -- stable sort *IN PLACE*; cmp(x, y) -> -1, 0, 1 """ pass def __add__(self, y): # real signature unknown; restored from __doc__ """ x.__add__(y) <==> x+y """ pass def __contains__(self, y): # real signature unknown; restored from __doc__ """ x.__contains__(y) <==> y in x """ pass def __delitem__(self, y): # real signature unknown; restored from __doc__ """ x.__delitem__(y) <==> del x[y] """ pass def __delslice__(self, i, j): # real signature unknown; restored from __doc__ """ x.__delslice__(i, j) <==> del x[i:j] Use of negative indices is not supported. """ pass def __eq__(self, y): # real signature unknown; restored from __doc__ """ x.__eq__(y) <==> x==y """ pass def __getattribute__(self, name): # real signature unknown; restored from __doc__ """ x.__getattribute__('name') <==> x.name """ pass def __getitem__(self, y): # real signature unknown; restored from __doc__ """ x.__getitem__(y) <==> x[y] """ pass def __getslice__(self, i, j): # real signature unknown; restored from __doc__ """ x.__getslice__(i, j) <==> x[i:j] Use of negative indices is not supported. """ pass def __ge__(self, y): # real signature unknown; restored from __doc__ """ x.__ge__(y) <==> x>=y """ pass def __gt__(self, y): # real signature unknown; restored from __doc__ """ x.__gt__(y) <==> x>y """ pass def __iadd__(self, y): # real signature unknown; restored from __doc__ """ x.__iadd__(y) <==> x+=y """ pass def __imul__(self, y): # real signature unknown; restored from __doc__ """ x.__imul__(y) <==> x*=y """ pass def __init__(self, seq=()): # known special case of list.__init__ """ list() -> new empty list list(iterable) -> new list initialized from iterable's items # (copied from class doc) """ pass def __iter__(self): # real signature unknown; restored from __doc__ """ x.__iter__() <==> iter(x) """ pass def __len__(self): # real signature unknown; restored from __doc__ """ x.__len__() <==> len(x) """ pass def __le__(self, y): # real signature unknown; restored from __doc__ """ x.__le__(y) <==> x<=y """ pass def __lt__(self, y): # real signature unknown; restored from __doc__ """ x.__lt__(y) <==> x<y """ pass def __mul__(self, n): # real signature unknown; restored from __doc__ """ x.__mul__(n) <==> x*n """ pass @staticmethod # known case of __new__ def __new__(S, *more): # real signature unknown; restored from __doc__ """ T.__new__(S, ...) -> a new object with type S, a subtype of T """ pass def __ne__(self, y): # real signature unknown; restored from __doc__ """ x.__ne__(y) <==> x!=y """ pass def __repr__(self): # real signature unknown; restored from __doc__ """ x.__repr__() <==> repr(x) """ pass def __reversed__(self): # real signature unknown; restored from __doc__ """ L.__reversed__() -- return a reverse iterator over the list """ pass def __rmul__(self, n): # real signature unknown; restored from __doc__ """ x.__rmul__(n) <==> n*x """ pass def __setitem__(self, i, y): # real signature unknown; restored from __doc__ """ x.__setitem__(i, y) <==> x[i]=y """ pass def __setslice__(self, i, j, y): # real signature unknown; restored from __doc__ """ x.__setslice__(i, j, y) <==> x[i:j]=y Use of negative indices is not supported. """ pass def __sizeof__(self): # real signature unknown; restored from __doc__ """ L.__sizeof__() -- size of L in memory, in bytes """ pass __hash__ = None list
4、元组
4.1 元组介绍
元组由逗号分割的若干值组成,例如:
>>> t = 1,2,3,4,"acg" # 不带大括号括号也是可以的 >>> type(t) <class 'tuple'> >>> t = (1,2,3,4,"acg") >>> type(t) <class 'tuple'> # 元组可以嵌套 >>> u = t,(1,3,4,5) >>> u ((1, 2, 3, 4, 'acg'), (1, 3, 4, 5)) >>> type(u) <class 'tuple'> # 元组内容是不能改变的 >>> t[0] = 23 Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: 'tuple' object does not support item assignment # 但是元组内包含可变的对象 >>> a = ([1,3,4],[2,34,3]) >>> type(a) <class 'tuple'> >>> a[0][0]=11 >>> a ([11, 3, 4], [2, 34, 3])
元组在输出时总是有括号的,以便于正确表达嵌套结构;在输入时括号可有可无,不过括号经常都是必须的。不能给元组中单独的一个元素赋值,不过可以创建包含可变对象(例如列表)的元组。
4.2 元组和列表区别
元组的作用:元组能实现的功能列表都能实现,工作中使用元组多数是提醒他人这个是一个元组,无法更改内容
>>> t = (1,2,3,4,'a','list')
>>> type(t)
<class 'tuple'>
>>> dir(t)
[......省略, 'count', 'index']
元组互相转换列表(实现了元组的修改)
元组-->列表
>>> t (1, 2, 3, 4, 'a', 'list') >>> list(t) [1, 2, 3, 4, 'a', 'list']
列表-->元组
>>> a
[1, 2, 3, 4, 6, 'a', 'b', 'c', 'd', 4, 24, 6, 'A', 'l', 'e', 'x', ' ', 'L', 'i']
>>> tuple(a)
(1, 2, 3, 4, 6, 'a', 'b', 'c', 'd', 4, 24, 6, 'A', 'l', 'e', 'x', ' ', 'L', 'i')
class tuple(object): """ tuple() -> empty tuple tuple(iterable) -> tuple initialized from iterable's items If the argument is a tuple, the return value is the same object. """ def count(self, value): # real signature unknown; restored from __doc__ """ T.count(value) -> integer -- return number of occurrences of value """ return 0 def index(self, value, start=None, stop=None): # real signature unknown; restored from __doc__ """ T.index(value, [start, [stop]]) -> integer -- return first index of value. Raises ValueError if the value is not present. """ return 0 def __add__(self, y): # real signature unknown; restored from __doc__ """ x.__add__(y) <==> x+y """ pass def __contains__(self, y): # real signature unknown; restored from __doc__ """ x.__contains__(y) <==> y in x """ pass def __eq__(self, y): # real signature unknown; restored from __doc__ """ x.__eq__(y) <==> x==y """ pass def __getattribute__(self, name): # real signature unknown; restored from __doc__ """ x.__getattribute__('name') <==> x.name """ pass def __getitem__(self, y): # real signature unknown; restored from __doc__ """ x.__getitem__(y) <==> x[y] """ pass def __getnewargs__(self, *args, **kwargs): # real signature unknown pass def __getslice__(self, i, j): # real signature unknown; restored from __doc__ """ x.__getslice__(i, j) <==> x[i:j] Use of negative indices is not supported. """ pass def __ge__(self, y): # real signature unknown; restored from __doc__ """ x.__ge__(y) <==> x>=y """ pass def __gt__(self, y): # real signature unknown; restored from __doc__ """ x.__gt__(y) <==> x>y """ pass def __hash__(self): # real signature unknown; restored from __doc__ """ x.__hash__() <==> hash(x) """ pass def __init__(self, seq=()): # known special case of tuple.__init__ """ tuple() -> empty tuple tuple(iterable) -> tuple initialized from iterable's items If the argument is a tuple, the return value is the same object. # (copied from class doc) """ pass def __iter__(self): # real signature unknown; restored from __doc__ """ x.__iter__() <==> iter(x) """ pass def __len__(self): # real signature unknown; restored from __doc__ """ x.__len__() <==> len(x) """ pass def __le__(self, y): # real signature unknown; restored from __doc__ """ x.__le__(y) <==> x<=y """ pass def __lt__(self, y): # real signature unknown; restored from __doc__ """ x.__lt__(y) <==> x<y """ pass def __mul__(self, n): # real signature unknown; restored from __doc__ """ x.__mul__(n) <==> x*n """ pass @staticmethod # known case of __new__ def __new__(S, *more): # real signature unknown; restored from __doc__ """ T.__new__(S, ...) -> a new object with type S, a subtype of T """ pass def __ne__(self, y): # real signature unknown; restored from __doc__ """ x.__ne__(y) <==> x!=y """ pass def __repr__(self): # real signature unknown; restored from __doc__ """ x.__repr__() <==> repr(x) """ pass def __rmul__(self, n): # real signature unknown; restored from __doc__ """ x.__rmul__(n) <==> n*x """ pass def __sizeof__(self): # real signature unknown; restored from __doc__ """ T.__sizeof__() -- size of T in memory, in bytes """ pass tuple
5、字典
5.1 字典介绍
与序列不同,序列由数字做索引,字典由键做索引,键可以是任意不可变类型;字符串和数字永远可以拿来做键。如果元组只包含字符串、 数字或元组,它们可以用作键;如果元组直接或间接地包含任何可变对象,不能用作键。你不能用列表作为键,因为列表可以用索引、切片或者像 append() 和extend() 这样的方法修改。
理解字典的最佳方式是把它看做无序的 键:值 对集合,要求是键必须是唯一的(在同一个字典内)。一对大括号将创建一个空的字典: {}。大括号中由逗号分隔的 键:值 对将成为字典的初始值;打印字典时也是按照这种方式输出。
字典的主要操作是依据键来存取值。也可以通过 del 删除 一个 键:值 对。如果你用一个已经存在的键存储值,那么以前为该键分配的值就会被覆盖。从一个不存在的键中读取值会导致错误。
list(d.keys())返回字典中所有键组成的列表,列表的顺序是随机的(如果你想它是有序的,就用sorted(d.keys())代替)。[2]要检查某个键是否在字典中,可以使用 in 关键字。
Python 2.x
clear:清除字典中的所有元素
copy:浅拷贝
fromkeys:从序列键和值设置为value来创建一个新的字典
get:如果该键在字典中存在,获取对应的值;如果该键在字典中不存在,默认返回none,也可以设置一个默认的返回值
has_key:判断key是否存在 Python 3.x已经废弃 key in id_db 判断即可
items:获取字典中的键值对放在列表中,键值对作为已元组的形式作为列表中的元素
iteritems
iterkeys
itervalues
keys:获取字典中的键
pop:删除字典中键(key)所在的键值对
popitem:随机删除字典中的元素
setdefault:设置字典中键对应的初始值,如果键值都存在,则显示的是原来的初始值,如果不存在,默认显示none,不默认的话,可是设置一个初始值。
update:把第二个字典中的键值对更新到第一个字典中
values:获取字典的值
viewitems
viewkeys
viewvalues
Python 3.x
clear:清除字典中的所有元素
copy:浅拷贝
fromkeys:从序列键和值设置为value来创建一个新的字典(有坑)
get:如果该键在字典中存在,获取对应的值;如果该键在字典中不存在,默认返回none,也可以设置一个默认的返回值 使用索引也能取值但是存在key不存在报错问题
items:获取字典中的键值对放在列表中,键值对作为已元组的形式作为列表中的元素(字典变列表 数据量很大会很耗时 不要使用)
keys:获取字典中的键
pop:删除字典中键(key)所在的键值对 也可以使用del删除字典元素
popitem:随机删除字典中的元素
setdefault:设置字典中键对应的初始值,如果键值都存在,则显示的是原来的初始值,如果不存在,默认显示none,不默认的话,可是设置一个初始值。
update:把第二个字典中的键值对更新到第一个字典中 key如果已经存在会覆盖不会更新
values:获取字典的值
class dict(object): """ dict() -> new empty dictionary dict(mapping) -> new dictionary initialized from a mapping object's (key, value) pairs dict(iterable) -> new dictionary initialized as if via: d = {} for k, v in iterable: d[k] = v dict(**kwargs) -> new dictionary initialized with the name=value pairs in the keyword argument list. For example: dict(one=1, two=2) """ def clear(self): # real signature unknown; restored from __doc__ """ 清除内容 """ """ D.clear() -> None. Remove all items from D. """ pass def copy(self): # real signature unknown; restored from __doc__ """ 浅拷贝 """ """ D.copy() -> a shallow copy of D """ pass @staticmethod # known case def fromkeys(S, v=None): # real signature unknown; restored from __doc__ """ dict.fromkeys(S[,v]) -> New dict with keys from S and values equal to v. v defaults to None. """ pass def get(self, k, d=None): # real signature unknown; restored from __doc__ """ 根据key获取值,d是默认值 """ """ D.get(k[,d]) -> D[k] if k in D, else d. d defaults to None. """ pass def has_key(self, k): # real signature unknown; restored from __doc__ """ 是否有key """ """ D.has_key(k) -> True if D has a key k, else False """ return False def items(self): # real signature unknown; restored from __doc__ """ 所有项的列表形式 """ """ D.items() -> list of D's (key, value) pairs, as 2-tuples """ return [] def iteritems(self): # real signature unknown; restored from __doc__ """ 项可迭代 """ """ D.iteritems() -> an iterator over the (key, value) items of D """ pass def iterkeys(self): # real signature unknown; restored from __doc__ """ key可迭代 """ """ D.iterkeys() -> an iterator over the keys of D """ pass def itervalues(self): # real signature unknown; restored from __doc__ """ value可迭代 """ """ D.itervalues() -> an iterator over the values of D """ pass def keys(self): # real signature unknown; restored from __doc__ """ 所有的key列表 """ """ D.keys() -> list of D's keys """ return [] def pop(self, k, d=None): # real signature unknown; restored from __doc__ """ 获取并在字典中移除 """ """ D.pop(k[,d]) -> v, remove specified key and return the corresponding value. If key is not found, d is returned if given, otherwise KeyError is raised """ pass def popitem(self): # real signature unknown; restored from __doc__ """ 获取并在字典中移除 """ """ D.popitem() -> (k, v), remove and return some (key, value) pair as a 2-tuple; but raise KeyError if D is empty. """ pass def setdefault(self, k, d=None): # real signature unknown; restored from __doc__ """ 如果key不存在,则创建,如果存在,则返回已存在的值且不修改 """ """ D.setdefault(k[,d]) -> D.get(k,d), also set D[k]=d if k not in D """ pass def update(self, E=None, **F): # known special case of dict.update """ 更新 {'name':'alex', 'age': 18000} [('name','sbsbsb'),] """ """ 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] """ pass def values(self): # real signature unknown; restored from __doc__ """ 所有的值 """ """ D.values() -> list of D's values """ return [] def viewitems(self): # real signature unknown; restored from __doc__ """ 所有项,只是将内容保存至view对象中 """ """ D.viewitems() -> a set-like object providing a view on D's items """ pass def viewkeys(self): # real signature unknown; restored from __doc__ """ D.viewkeys() -> a set-like object providing a view on D's keys """ pass def viewvalues(self): # real signature unknown; restored from __doc__ """ D.viewvalues() -> an object providing a view on D's values """ pass def __cmp__(self, y): # real signature unknown; restored from __doc__ """ x.__cmp__(y) <==> cmp(x,y) """ pass def __contains__(self, k): # real signature unknown; restored from __doc__ """ D.__contains__(k) -> True if D has a key k, else False """ return False def __delitem__(self, y): # real signature unknown; restored from __doc__ """ x.__delitem__(y) <==> del x[y] """ pass def __eq__(self, y): # real signature unknown; restored from __doc__ """ x.__eq__(y) <==> x==y """ pass def __getattribute__(self, name): # real signature unknown; restored from __doc__ """ x.__getattribute__('name') <==> x.name """ pass def __getitem__(self, y): # real signature unknown; restored from __doc__ """ x.__getitem__(y) <==> x[y] """ pass def __ge__(self, y): # real signature unknown; restored from __doc__ """ x.__ge__(y) <==> x>=y """ pass def __gt__(self, y): # real signature unknown; restored from __doc__ """ x.__gt__(y) <==> x>y """ pass def __init__(self, seq=None, **kwargs): # known special case of dict.__init__ """ dict() -> new empty dictionary dict(mapping) -> new dictionary initialized from a mapping object's (key, value) pairs dict(iterable) -> new dictionary initialized as if via: d = {} for k, v in iterable: d[k] = v dict(**kwargs) -> new dictionary initialized with the name=value pairs in the keyword argument list. For example: dict(one=1, two=2) # (copied from class doc) """ pass def __iter__(self): # real signature unknown; restored from __doc__ """ x.__iter__() <==> iter(x) """ pass def __len__(self): # real signature unknown; restored from __doc__ """ x.__len__() <==> len(x) """ pass def __le__(self, y): # real signature unknown; restored from __doc__ """ x.__le__(y) <==> x<=y """ pass def __lt__(self, y): # real signature unknown; restored from __doc__ """ x.__lt__(y) <==> x<y """ pass @staticmethod # known case of __new__ def __new__(S, *more): # real signature unknown; restored from __doc__ """ T.__new__(S, ...) -> a new object with type S, a subtype of T """ pass def __ne__(self, y): # real signature unknown; restored from __doc__ """ x.__ne__(y) <==> x!=y """ pass def __repr__(self): # real signature unknown; restored from __doc__ """ x.__repr__() <==> repr(x) """ pass def __setitem__(self, i, y): # real signature unknown; restored from __doc__ """ x.__setitem__(i, y) <==> x[i]=y """ pass def __sizeof__(self): # real signature unknown; restored from __doc__ """ D.__sizeof__() -> size of D in memory, in bytes """ pass __hash__ = None dict
练习:元素分类
有如下值集合 [11,22,33,44,55,66,77,88,99,90...],将所有大于 66 的值保存至字典的第一个key中,将小于 66 的值保存至第二个key的值中。
即:{'k1': 大于66 , 'k2': 小于66}
name = [11,22,33,44,55,66,77,88,99,90] k1 = [] k2 = [] k = {"k1":k1,"k2":k2} for i in name: if i > 66: k1.append(i) else: k2.append(i) print(k)
5.2 字典遍历技巧
# 字典遍历时,键和对应的值通过使用items()方法可以同时得到。 >>> knights = {'gallahad': 'the pure', 'robin': 'the brave'} >>> for k, v in knights.items(): ... print(k, v) ... gallahad the pure robin the brave # 序列中遍历时,使用 enumerate() 函数可以同时得到索引和对应的值。 >>> for i, v in enumerate(['tic', 'tac', 'toe']): ... print(i, v) ... 0 tic 1 tac 2 toe # 同时遍历两个或更多的序列,使用 zip() 函数可以成对读取元素。 >>> questions = ['name', 'quest', 'favorite color'] >>> answers = ['lancelot', 'the holy grail', 'blue'] >>> for q, a in zip(questions, answers): ... print('What is your {0}? It is {1}.'.format(q, a)) ... What is your name? It is lancelot. What is your quest? It is the holy grail. What is your favorite color? It is blue. # 要反向遍历一个序列,首先正向生成这个序列,然后调用 reversed() 函数。 >>> for i in reversed(range(1, 10, 2)): ... print(i) ... 9 7 5 3 1 # 按排序顺序遍历一个序列,请使用sorted()函数,返回一个新的排序的列表,同时保留源不变。 >>> basket = ['apple', 'orange', 'apple', 'pear', 'orange', 'banana'] >>> for f in sorted(set(basket)): ... print(f) ... apple banana orange pear # 若要在遍历内部修改正在迭代的序列(例如复制某些元素),建议您首先制作副本。在序列上循环不会隐式地创建副本。切片表示法使这尤其方便: >>> words = ['cat', 'window', 'defenestrate'] >>> for w in words[:]: # Loop over a slice copy of the entire list. ... if len(w) > 6: ... words.insert(0, w) ... >>> words ['defenestrate', 'cat', 'window', 'defenestrate']
for k,v in id_db.items(): # 效率低 字典变列表 数据量很大会很耗时 print(k,v) for key in id_db: print(key) for key in id_db: # 效率高 print(key,id_db[key])
6、运算符运算
这篇文章写得很详细了,用到的话直接参考:http://www.runoob.com/python/python-operators.html
常见应用场景
10 % 2 # 返回余数 应用一个表格通过判断余数显示不同的颜色
7、set集合
set是一个无序且不重复的元素集合,集合中的元素不会重复且没有顺序。集合的基本用途包括成员测试和消除重复条目。集合对象还支持并集、 交集、 差和对称差等数学运算。
# set创建 # 方法1:se = set() 调用类的__init__功能 内部执行for循环,循环元组内容添加到set集合 se = set() li = [11,22,11,22,] s1 = set(li) print("s1:",s1,type(s1)) # 方法2:se = {} 调用方法1实现 s1 = {11,22,} print("s1:",s1,type(s1)) 结果: 均是 s1: {11, 22} <class 'set'> # add--添加元素 >>> set1 = set() >>> set1.add("mads") >>> set1 {'mads'} >>> set1.add("mads") # 元素不重复,多次添加只有一个 >>> set1 {'mads'} >>> set1.add("cl") >>> set1 {'cl', 'mads'} # clear--清空 >>> set1.clear() >>> set1 set([]) # copy--拷贝(浅拷贝) # difference--删除当前set中的所有包含在 new set 里的元素 # symmetric_difference--差集,创建新对象 s1 = {11,22,33} s2 = {22,33,44} s3 = s1.difference(s2) # s1 中存在 s2中不存在 的元素 s3 = s2.difference(s1) # s2 中存在 s1中不存在 的元素 s3 = s1.symmetric_difference(s2) # s1 中存在 s2中不存在 的元素 + s2 中存在 s1中不存在 的元素 print("s1:",s1) print("s2:",s2) print("s3:",s3) # difference_update--删除当前set中的所有包含在 new set 里的元素 s1 = {11,22,33} s2 = {22,33,44} s3 = s1.difference(s2) # s1 中存在 s2中不存在 的元素 s1.difference_update(s2) print("s1:",s1) print("s2:",s2) print("s3:",s3) # symmetric_difference_update--差集,改变原来 s1 = {11,22,33} s2 = {22,33,44} s3 = s1.symmetric_difference(s2) # s1 中存在 s2中不存在 的元素 + s2 中存在 s1中不存在 的元素 s1.symmetric_difference_update(s2) print("s1:",s1) print("s2:",s2) print("s3:",s3) # discard--移除元素不存在也不报错,移除成功与否都无返回值 # 元素存在,正常移除 s1 = {11,22,33} s1.discard(11) print(s1) 结果: {22,33} # 元素不存在,不报错 s1 = {11,22,33} s1.discard(1111) print(s1) 结果: {11,22,33} # pop--随机移除元素,并返回移除元素值,并非最后一个元素(set集合都事无序的) s1 = {11,22,33,332,123,9,120,2824,12} res = s1.pop() print(s1,type(s1)) print(res) 结果: {2824, 9, 11, 12, 332, 22, 120, 123} <class 'set'> 33 # remove--移除指定的元素 >>> set1 {'mads', 'lyl'} >>> set1.remove('lyl') >>> set1 set() # intersection--取交集,新创建一个set s1 = {11,22,33} s2 = {22,33,44} s3 = s1.intersection(s2) # 取差集 s4 = s2.intersection(s1) # 同上没有差异,等效 print("s1:",s1) print("s2:",s2) print("s3:",s3) print("s4:",s4) 结果: s1: {33, 11, 22} s2: {33, 44, 22} s3: {33, 22} s4: {33, 22} # intersection_update--取交集,修改原来set s1 = {11,22,33} s2 = {22,33,44} s3 = s1.intersection(s2) # 取差集 s1.intersection_update(s2) print("s1:",s1) print("s2:",s2) print("s3:",s3) 结果: s1: {33, 22} s2: {33, 44, 22} s3: {33, 22} # issubset--是否是子集 # issuperset--是否是父集 s1 = {22,33} s2 = {22,33,44} res1 = s1.issubset(s2) # 判断s1是否是s2的子集 res2 = s1.issuperset(s2) # 判断s1是否是s2的父集 print("s1:",s1) print("s2:",s2) print("判断s1是否是s2的子集:",res1) print("判断s1是否是s2的父集:",res2) 结果: s1: {33, 22} s2: {33, 44, 22} 判断s1是否是s2的子集: True 判断s1是否是s2的父集: False # isdisjoint--如果没有交集,返回true # union--并集 s1 = {11,22,33} s2 = {22,33,44} res = s1.isdisjoint(s2) # s1和s2是否有交集,没有交集返回True,有交集返回False s3 = s1.union(s2) print("s1:",s1) print("s2:",s2) print("s3:",s3) print(res) # update--更新 s1 = {11,22,33} s2 = {22,33,44} s1.update(s2) # 把s2更新到s1中,因为set集合是无序不重复的,会去掉s1和s2中重复的元素值 print("s1:",s1) print("s2:",s2) 结果: s1: {33, 22, 11, 44} s2: {33, 44, 22}
class set(object): """ set() -> new empty set object set(iterable) -> new set object Build an unordered collection of unique elements. """ def add(self, *args, **kwargs): # real signature unknown """ 添加 """ """ Add an element to a set. This has no effect if the element is already present. """ pass def clear(self, *args, **kwargs): # real signature unknown """ Remove all elements from this set. """ pass def copy(self, *args, **kwargs): # real signature unknown """ Return a shallow copy of a set. """ pass def difference(self, *args, **kwargs): # real signature unknown """ Return the difference of two or more sets as a new set. (i.e. all elements that are in this set but not the others.) """ pass def difference_update(self, *args, **kwargs): # real signature unknown """ 删除当前set中的所有包含在 new set 里的元素 """ """ Remove all elements of another set from this set. """ pass def discard(self, *args, **kwargs): # real signature unknown """ 移除元素 """ """ Remove an element from a set if it is a member. If the element is not a member, do nothing. """ pass def intersection(self, *args, **kwargs): # real signature unknown """ 取交集,新创建一个set """ """ Return the intersection of two or more sets as a new set. (i.e. elements that are common to all of the sets.) """ pass def intersection_update(self, *args, **kwargs): # real signature unknown """ 取交集,修改原来set """ """ Update a set with the intersection of itself and another. """ pass def isdisjoint(self, *args, **kwargs): # real signature unknown """ 如果没有交集,返回true """ """ Return True if two sets have a null intersection. """ pass def issubset(self, *args, **kwargs): # real signature unknown """ 是否是子集 """ """ Report whether another set contains this set. """ pass def issuperset(self, *args, **kwargs): # real signature unknown """ 是否是父集 """ """ Report whether this set contains another set. """ pass def pop(self, *args, **kwargs): # real signature unknown """ 移除 """ """ Remove and return an arbitrary set element. Raises KeyError if the set is empty. """ pass def remove(self, *args, **kwargs): # real signature unknown """ 移除 """ """ Remove an element from a set; it must be a member. If the element is not a member, raise a KeyError. """ pass def symmetric_difference(self, *args, **kwargs): # real signature unknown """ 差集,创建新对象""" """ Return the symmetric difference of two sets as a new set. (i.e. all elements that are in exactly one of the sets.) """ pass def symmetric_difference_update(self, *args, **kwargs): # real signature unknown """ 差集,改变原来 """ """ Update a set with the symmetric difference of itself and another. """ pass def union(self, *args, **kwargs): # real signature unknown """ 并集 """ """ Return the union of sets as a new set. (i.e. all elements that are in either set.) """ pass def update(self, *args, **kwargs): # real signature unknown """ 更新 """ """ Update a set with the union of itself and others. """ pass def __and__(self, y): # real signature unknown; restored from __doc__ """ x.__and__(y) <==> x&y """ pass def __cmp__(self, y): # real signature unknown; restored from __doc__ """ x.__cmp__(y) <==> cmp(x,y) """ pass def __contains__(self, y): # real signature unknown; restored from __doc__ """ x.__contains__(y) <==> y in x. """ pass def __eq__(self, y): # real signature unknown; restored from __doc__ """ x.__eq__(y) <==> x==y """ pass def __getattribute__(self, name): # real signature unknown; restored from __doc__ """ x.__getattribute__('name') <==> x.name """ pass def __ge__(self, y): # real signature unknown; restored from __doc__ """ x.__ge__(y) <==> x>=y """ pass def __gt__(self, y): # real signature unknown; restored from __doc__ """ x.__gt__(y) <==> x>y """ pass def __iand__(self, y): # real signature unknown; restored from __doc__ """ x.__iand__(y) <==> x&=y """ pass def __init__(self, seq=()): # known special case of set.__init__ """ set() -> new empty set object set(iterable) -> new set object Build an unordered collection of unique elements. # (copied from class doc) """ pass def __ior__(self, y): # real signature unknown; restored from __doc__ """ x.__ior__(y) <==> x|=y """ pass def __isub__(self, y): # real signature unknown; restored from __doc__ """ x.__isub__(y) <==> x-=y """ pass def __iter__(self): # real signature unknown; restored from __doc__ """ x.__iter__() <==> iter(x) """ pass def __ixor__(self, y): # real signature unknown; restored from __doc__ """ x.__ixor__(y) <==> x^=y """ pass def __len__(self): # real signature unknown; restored from __doc__ """ x.__len__() <==> len(x) """ pass def __le__(self, y): # real signature unknown; restored from __doc__ """ x.__le__(y) <==> x<=y """ pass def __lt__(self, y): # real signature unknown; restored from __doc__ """ x.__lt__(y) <==> x<y """ pass @staticmethod # known case of __new__ def __new__(S, *more): # real signature unknown; restored from __doc__ """ T.__new__(S, ...) -> a new object with type S, a subtype of T """ pass def __ne__(self, y): # real signature unknown; restored from __doc__ """ x.__ne__(y) <==> x!=y """ pass def __or__(self, y): # real signature unknown; restored from __doc__ """ x.__or__(y) <==> x|y """ pass def __rand__(self, y): # real signature unknown; restored from __doc__ """ x.__rand__(y) <==> y&x """ pass def __reduce__(self, *args, **kwargs): # real signature unknown """ Return state information for pickling. """ pass def __repr__(self): # real signature unknown; restored from __doc__ """ x.__repr__() <==> repr(x) """ pass def __ror__(self, y): # real signature unknown; restored from __doc__ """ x.__ror__(y) <==> y|x """ pass def __rsub__(self, y): # real signature unknown; restored from __doc__ """ x.__rsub__(y) <==> y-x """ pass def __rxor__(self, y): # real signature unknown; restored from __doc__ """ x.__rxor__(y) <==> y^x """ pass def __sizeof__(self): # real signature unknown; restored from __doc__ """ S.__sizeof__() -> size of S in memory, in bytes """ pass def __sub__(self, y): # real signature unknown; restored from __doc__ """ x.__sub__(y) <==> x-y """ pass def __xor__(self, y): # real signature unknown; restored from __doc__ """ x.__xor__(y) <==> x^y """ pass __hash__ = None set
应用案例:寻找差异
# 数据库中原有 old_dict = { "#1":{ 'hostname':c1, 'cpu_count': 2, 'mem_capicity': 80 }, "#2":{ 'hostname':c1, 'cpu_count': 2, 'mem_capicity': 80 }, "#3":{ 'hostname':c1, 'cpu_count': 2, 'mem_capicity': 80 } } # cmdb 新汇报的数据 new_dict = { "#1":{ 'hostname':c1, 'cpu_count': 2, 'mem_capicity': 800 }, "#3":{ 'hostname':c1, 'cpu_count': 2, 'mem_capicity': 80 }, "#4":{ 'hostname':c2, 'cpu_count': 2, 'mem_capicity': 80 } }
问题分析:
需要解决的事:
1)新增的数据要添加进去
2)已经有的数据要更新内容
3)删除的信息要去掉
old_dict.keys()
new_dict.keys()
交集:即要更新的内容
8、collection模块
8.1 collection模块介绍(系统已经自带)
我们都知道,Python拥有一些内置的数据类型,比如str, int, list, tuple, dict等, collections模块在这些内置数据类型的基础上,提供了几个额外的数据类型:
namedtuple(): 生成可以使用名字来访问元素内容的tuple子类
deque: 双端队列,可以快速的从另外一侧追加和推出对象
Counter: 计数器,主要用来计数
OrderedDict: 有序字典
defaultdict: 带有默认值的字典
7.1.1 计数器(counter)
功能:是对字典类型的补充,用于追踪值得出现次数 除了具备字典的所有的功能+自己的功能
>>> import collections
>>> str1 = "adferwer" >>> obj = collections.Counter(str1) >>> print(obj) Counter({'r': 2, 'e': 2, 'w': 1, 'd': 1, 'a': 1, 'f': 1})
8.1.2 有序字典(OrderedDict)
记录了字典元素添加的顺序
import collections #自己动手实现一个有序的字典 dict1 = {"aa":2,"bb":32,"cc":232} #print(dict1) # 多次输出查看结果是无序的 list1 = ["aa","bb","cc"] # 序列有序的 for i in list1: # 多次执行结果输出顺序不变,即通过字典+列表实现了一个有序的字典 print(i,dict1[i]) obj = collections.OrderedDict() # 用collections实现有序字典 obj["aa"] = 2 obj["bb"] = 32 obj["cc"] = 232 print(obj)
8.1.3 默认字典
需求问题
有如下值集合 [11,22,33,44,55,66,77,88,99,90...],将所有大于 66 的值保存至字典的第一个key中,将小于 66 的值保存至第二个key的值中。 即: {'k1': 大于66 , 'k2': 小于66}
name = [11,22,33,44,55,66,77,88,99,90] k1 = [] k2 = [] k = {"k1":k1,"k2":k2} for i in name: if i > 66: k1.append(i) else: k2.append(i) print(k)
import collections name = [11,22,33,44,55,66,77,88,99,90] obj = collections.defaultdict(list) for i in name: if i >66: obj["k1"].append(i) else: obj["k2"].append(i) print(obj)
8.1.4 可命名元组(namedtuple)
坐标应用
import collections mydict = collections.namedtuple("mydict",["x","y","z"]) obj = mydict("111","222","333") print(obj.x) print(obj.y) print(obj.z)
结果:111 222 333
8.1.5 双向队列(deque)
一个线程安全的双向队列
import collections d = collections.deque() d.append("aa") d.appendleft("cc") d.appendleft("aa") d.appendleft("bb") # 从队列左侧插入 print(d) r = d.count("aa") # 元素数量统计 print(r) d.extend(["dd","ff","gg"]) # 扩展 print(d) index = d.index("aa") # 元素位置,默认从左到右 print(index)
注:既然有双向队列,也有单项队列(先进先出 FIFO )
import queue q = queue.Queue() q.put(1) # 添加元素 print("queue size:",q.qsize()) # 单队列大小 res = q.get(1) # 获取元素 print(res)
出处:http://www.cnblogs.com/madsnotes/
声明:本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接。