Python学习笔记(一) # _*_ coding:gb2312 _*_ :这样制定程序的编码; 建议如果使用中文,最好用utf-8 (用utf-8的时候,),或者gb2312。 复数 可以直接表示复数a =1.5+0.5j; a.real :取得实部 a.imag :取得虚部 abs(a):取得模 数据类型转换 float(),int(),long() 我们用a**b 表示 a的b次方 开方依然是函数 sqrt(a) 最近一次表达式输出,保存在 _ 变量中 字符串可以通过几种方式分行。可以在行加反斜杠做为继续符,这表示下一行是当前行的逻辑沿续。 eg: hello ="This is a rather long string containing\n\ several lines of text just as you would do in C.\n\ Note that whitespace at the beginning of the line is\ significant." print hello 然而,如果我们创建一个“行”("raw")字符串,\ n序列就不会转为换行,源码中的反斜杠和换行符n都会做为字符串中的数据处理。如下所示: hello = r"This is a rather long string containing\n\ several lines of text much as you would do in C." print hello would print: 会打印为: This is a rather long string containing\n\ several lines of text much as you would do in C. 另外,字符串可以用一对三重引号”””或'''来标识。三重引号中的字符串在行尾不需要换行标记,所有的格式都会包括在字符串中。 print """ Usage: thingy [OPTIONS] -h Display this usage message -H hostname Hostname to connect to """ produces the following output: 生成以下输出: Usage: thingy [OPTIONS] -h Display this usage message -H hostname Hostname to connect to 联想到HTML 中的pre标签。 Python 已经有了几个复合数据类型,用于组织其它的值。最通用的是链表,它写为中括之间用逗号分隔的一列值(子项),链表的子项不一定是同一类型的值。 >>> a = ['spam', 'eggs', 100, 1234] 内置函数len()也同样可以用于链表: >>> len(a) if 语句 if x == 1: … elif x == 0: … else: … 可能会有零到多个 elif 部分,else 是可选的。关键字“elif” 是“ else if ”的缩写,这个可以有效避免过深的缩进。if elif elif 序列用于替代其它语言中的 switch 或 case 语句。 注意是elif 不是elseif。容易混淆吧。还有其中的冒号别忘了。 for语句 for x in a: print x, len(x) 类似java或者js中遍历对象的形式。记得加上冒号。 当然这和传统意义上的for语句差别还是很大。 range() 函数 如果你需要一个数值序列,内置函数range()可能会很有用,它生成一个等差级数链表。 >>> range(10) [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] range(10) 生成了一个包含10个值的链表,它准确的用链表的索引值填充了这个长度为10的列表,所生成的链表中不包括范围中的结束值。也可以让range操作从另一个数值开始,或者可以指定一个不同的步进值(甚至是负数,有时这也被称为“步长”): >>> range(5, 10) [5, 6, 7, 8, 9] >>> range(0, 10, 3) [0, 3, 6, 9] >>> range(-10, -100, -30) [-10, -40, -70] 需要迭代链表索引的话,如下所示结合使 用range() 和 len() : >>> a = ['Mary', 'had', 'a', 'little', 'lamb'] >>> for i in range(len(a)): print i, a[i] 0 Mary 1 had 2 a 3 little 4 lamb 在序列中循环时,索引位置和对应值可以使用enumerate()函数同时得到。 for i, v in enumerate(['tic', 'tac', 'toe']): print i, v 同时循环两个或更多的序列,可以使用 zip() 整体解读。 >>> questions = ['name', 'quest', 'favorite color'] >>> answers = ['lancelot', 'the holy grail', 'blue'] >>> for q, a in zip(questions, answers): print 'What is your %s? It is %s.' % (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. pass 语句 pass 语句什么也不做。它用于那些语法上必须要有什么语句,但程序什么也不做的场合,例如: >>> while True: pass def def fib(n): # write Fibonacci series up to n """Print a Fibonacci series up to n.""" a, b = 0, 1 while b < n: print b, a, b = b, a+b >>> # Now call the function we just defined: fib(2000) 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 关键字 def 引入了一个函数定义。在其后必须跟有函数名和包括形式参数的圆括号。函数体语句从下一行开始,必须是缩进的。函数体的第一行可以是一个字符串值,这个字符串是该函数的 (文档字符串(documentation string)),也可称作 docstring 。 深入链表 append( x) 把一个元素添加到链表的结尾,相当于 a[len(a):] = [x] extend( L) 通过添加指定链表的所有元素来扩充链表,相当于 a[len(a):] = L。 insert( i, x) 在指定位置插入一个元素。第一个参数是准备插入到其前面的那个元素的索引,例如a.insert(0, x) 会插入到整个链表之前,而a.insert(len(a), x) 相当于 a.append(x)。 remove( x) 删除链表中值为x的第一个元素。如果没有这样的元素,就会返回一个错误。 pop( [i]) 从链表的指定位置删除元素,并将其返回。如果没有指定索引,a.pop()返回最后一个元素。元素随即从链表中被删除。(方法中i两边的方括号表示这个参数是可选的,而不是要求你输入一对方括号,你会经常在Python 库参考手册中遇到这样的标记。) index( x) 返回链表中第一个值为x的元素的索引。如果没有匹配的元素就会返回一个错误。 count( x) 返回x在链表中出现的次数。 sort( ) 对链表中的元素进行适当的排序。 reverse( ) 倒排链表中的元素。 函数化编程工具 对于链表来讲,有三个内置函数非常有用:filter(), map(), 和 reduce()。 "filter(function, sequence)"返回一个序列(sequence),包括了给定序列中所有调用function(item)后返回值为true的元素。(如果可能的话,会返回相同的类型)。例如,以下程序可以计算部分素数: >>> def f(x): return x % 2 != 0 and x % 3 != 0 >>> filter(f, range(2, 25)) [5, 7, 11, 13, 17, 19, 23] "map(function, sequence)" 为每一个元素依次调用function(item)并将返回值组成一个链表返回。例如,以下程序计算立方: >>> def cube(x): return x*x*x >>> map(cube, range(1, 11)) [1, 8, 27, 64, 125, 216, 343, 512, 729, 1000] 两者区别: map返回的是 函数结果序列。filter返回的是函数返回结果为true的参数。(相当于过滤) 可以传入多个序列,函数也必须要有对应数量的参数,执行时会依次用各序列上对应的元素来调用函数(如果某些序列比其它的短,就用None来代替)。如果把None做为一个函数传入,则直接返回参数做为替代。例如: >>> seq = range(8) >>> def add(x, y): return x+y >>> map(add, seq, seq) [0, 2, 4, 6, 8, 10, 12, 14] "reduce(func, sequence)" 返回一个单值,它是这样构造的:首先以序列的前两个元素调用函数,再以返回值和第三个参数调用,依次执行下去。例如,以下程序计算1到10的整数之和: >>> def add(x,y): return x+y >>> reduce(add, range(1, 11)) 55 实际上这里就是从1加到10。 可以传入第三个参数做为初始值。如果序列是空的,就返回初始值,否则函数会先接收初始值和序列的第一个元素,然后是返回值和下一个元素,依此类推。例如: >>> def sum(seq): def add(x,y): return x+y return reduce(add, seq, 0) >>> sum(range(1, 11)) 55 >>> sum([]) 0 注意: sum([])中的[]是不可以省略的。表示的是一个链表。 链表推导式 以后再看 del 有一个方法可从链表中删除指定索引的元素:del 语句。这个方法也可以从链表中删除切片(之前我们是把一个空链表赋给切片)。例如: >>> a = [-1, 1, 66.6, 333, 333, 1234.5] >>> del a[0] >>> a [1, 66.6, 333, 333, 1234.5] >>> del a[2:4] >>> a [1, 66.6, 1234.5] del can also be used to delete entire variables: del 也可以用于删除整个变量: >>> del a Dictionaries 字典 一看这名字吓了跳,结果和C++中的pair 或者java中的hashmap一个德性的事物。当然javascript用数组就行了。下面来看看python中字典的特点与具体应用。 字典的主要操作是依据关键字来存储和析取值。也可以用 del来删除关键字:值对。如果你用一个已经存在的关键字存储值,以前为该关键字分配的值就会被遗忘。试图析取从一个不存在的关键字中读取值会导致错误。 字典的 keys()方法返回由所有关键字组成的链表,该链表的顺序不定(如果你需要它有序,只能调用关键字链表的sort() 方法)。使用字典的 has_key()方法可以检查字典中是否存在某一关键字。 eg: tel = {'jack': 4098, 'sape': 4139} tel['guido'] = 4127 print tel print tel['jack'] del tel['sape'] tel['irv'] = 4127 print tel print tel.keys() print tel.has_key('guido') 在字典中循环时,关键字和对应的值可以使用 iteritems()方法同时解读出来。 knights = {'gallahad': 'the pure', 'robin': 'the brave'} for k, v in knights.iteritems(): print k, v 模块 不用多说,C++中有 include ,java中 import dir() 内置函数 dir() 用于按模块名搜索模块定义,它返回一个字符串类型的存储列表 import sys print dir(sys) ['__displayhook__', '__doc__', '__excepthook__', '__name__', '__stderr__', '__stdin__', '__stdout__', '_current_frames', '_getframe', 'api_version', 'argv', 'builtin_module_names', 'byteorder', 'call_tracing', 'callstats', 'copyright', 'displayhook', 'dllhandle', 'exc_clear', 'exc_info', 'exc_type', 'excepthook', 'exec_prefix', 'executable', 'exit', 'exitfunc', 'getcheckinterval', 'getdefaultencoding', 'getfilesystemencoding', 'getrecursionlimit', 'getrefcount', 'getwindowsversion', 'hexversion', 'maxint', 'maxunicode', 'meta_path', 'modules', 'path', 'path_hooks', 'path_importer_cache', 'platform', 'prefix', 'setcheckinterval', 'setprofile', 'setrecursionlimit', 'settrace', 'stderr', 'stdin', 'stdout', 'subversion', 'version', 'version_info', 'warnoptions', 'winver'] dir() 不会列出内置函数和变量名。如果你想列出这些内容,它们在标准模块 __builtin__中定义: >>> import __builtin__ >>> dir(__builtin__) Packages 包通常是使用用“圆点模块名”的结构化模块命名空间。例如,名为 A.B 的模块表示了名为 "B" 的包中名为 "A" 的子模块。正如同用模块来保存不同的模块架构可以避免全局变量之间的相互冲突,使用圆点模块名保存像 NumPy 或 Python Imaging Library 之类的不同类库架构可以避免模块之间的命名冲突。 需要注意的是使用 from package import item 方式导入包时,这个子项(item)既可以是包中的一个子模块(或一个子包),也可以是包中定义的其它命名,像函数、类或变量。import 语句首先核对是否包中有这个子项,如果没有,它假定这是一个模块,并尝试加载它。如果没有找到它,会引发一个 ImportError 异常。 相反,使用类似import item.subitem.subsubitem 这样的语法时,这些子项必须是包,最后的子项可以是包或模块,但不能是前面子项中定义的类、函数或变量。