Python簡明語法

需要寫一個處理文件讀取的腳本,之前一直沒有接觸過python

很適合我這種半道出家的,有空要好好學學python,也算多了一個本事,嗯嗯,先把簡明語法貼來,沒事參考只用!

感謝總結的原作者,找不到原文出處...


1. 關於python的啓動
除了直接啓動進入解釋器之外(不要忘記文件結束符是^Z(win)和^D(*nix/Mac)),另外兩種方法也很常用:
python -c "a=int(raw_input('a=')); print a*3"
這是直接執行python語句而不必事先寫程序。注意整體用雙引號,python語言內部用單引號以免引起混淆。
python -i test.py
執行完後回到解釋器。注意-i必須在test.py之前。這個方法也適合-c的情形,如:
python -i -c "a=3"
需要注意的是不要用重定向 python < test.py,原因懶得說了。

2. 腳本的命令行參數
存在sys.argv裏。這是一個list.

3. 註釋
以#開頭,類似於C的//,爲單行註釋。

4. 輸出
用print. 注意複雜類型也可以直接打印,例如list. 比如
import sys
print sys.argv
最後加個逗號可以避免換行。注意每個逗號後實際被追加了一個空格。
print 'a',
print 'b'
由於python有自省功能,也可以打印變量的類型。
print type(sys.argv)
利用解釋器學習python的時候可以多用type(_)來確認上一次運行結果的類型。

5. 賦值
和一般的語言一樣,且可以是多重的,如
x = y = z = 0

6. 數值類型
整數、浮點數和複數都是支持的。

* 整數沒有大小限制:
print 111111111*111111111
print int('12345678987654321')

* 浮點數使用硬件IEEE浮點類型。
print 1.0/3
print float('0.123')   # constructor
print 0.1+0.1+0.1-0.3 # not zero!

* 高精度十進制浮點數在decimal模塊的Decimal類:
import decimal;
from decimal import Decimal
print Decimal(1)/Decimal(7)
decimal.getcontext().prec = 100   # change precision. default is 28
print Decimal(1)/Decimal(7)
print Decimal('0.1')+Decimal('0.1')+Decimal('0.1')-Decimal('0.3') # exactly zero

* 複數的實部和虛部都是float. 虛數單位用j或者J表示。
a=3+4j
print a.real
print a.imag
print abs(a)

7. 字符串
字符串常量可以用單引號、雙引號括起來,也可以用raw字符串r""或者多行串(用"""或者'''包圍)。
字符串是不可變的。
print 'a' + 'b'    # ab
print 'a' * 3      # aaa
print 'abcd'[2]    # c
print len('asdf') # 4
其中第3種用法在C裏是無效的。
slicing總是從左到右的,且都是左閉右開區間,因此[-2:]是最後兩個字符。

8. 字符串方法分類
判斷類
* isalnum()/isalpha()/isdigit()/islower()/isspace()/istitle()/isupper()

查找類
* endswith/startswith(s[,star[,end]]) # 返回bool型
* find/rfind/count(sub[,start[,end]])

變換
* expandtabs([tabsize])          # tabsize默認爲8
* replace(old,new[,count])       # 替換所有。如果有count, 則只替換前count個
* ljust/rjust(width[,fillchar])
* lower()/upper()/capitalize()/swapcase()/title()
* lstrip([chars])/rstrip([chars])/strip([chars])

Token處理類
* partition/rpartition(sep)      # 從第一次/最後一次出現處分開 e.g 'abc!=12'.partition('!=') returns ('abc','!=','12')
* split/rsplit(sep[,maxsplit])   # 'a--b---c'進行左/右split的結果不一樣. 默認是strip後用連續空格隔開
* join(seq)                      # e.g '-'.join(['a','b','c']) returns 'a-b-c'

8. 字符串格式化
格式化運算符爲%,適用於str和unicode,格式爲format % values。當要求單參數時values必須是非元組對象,否則
values必須是一個元組(個數和format的需要保持一致),或一個映射(如字典)。例:
print '%(language)s has %(#)03d quote types.' % \
           {'language': "Python", "#": 2}


9. 序列操作
參考:Library Reference的3.6節.
python有六種序列類型:str, unicode, list, tuple, buffer, xrange.
大多數序列都有以下操作:x in s, x not in s, s+t, s*n, n*s, s[i], s[i:j], s[i:j:k], len(s), min(s), max(s). i,j,n是整數。
注意乘法(重複操作)是淺拷貝,因此lists=[[]]*3;lists[0].append(3)後得到的是[[3],[3],[3]].
str的in/not in操作可以用來作模式匹配,而不僅僅用來查找單個字符。

10. 列表
列表(lists)是最常用的序列類型,它的各個元素不必有相同的類型。
列表是可變的,甚至可以對它的slice賦值。一些經典的例子。
>>> # Replace some items:
... a[0:2] = [1, 12]
>>> a
[1, 12, 123, 1234]
>>> # Remove some:
... a[0:2] = []
>>> a
[123, 1234]
>>> # Insert some:
... a[1:1] = ['bletch', 'xyzzy']
>>> a
[123, 'bletch', 'xyzzy', 1234]
>>> # Insert (a copy of) itself at the beginning
>>> a[:0] = a
>>> a
[123, 'bletch', 'xyzzy', 1234, 123, 'bletch', 'xyzzy', 1234]
>>> # Clear the list: replace all items with an empty list
>>> a[:] = []
>>> a
[]

11. 基本控制流
注意python是靠的縮進而不是begin/end或者{}來指定的語句塊。語句塊至少要有一條語句,如果實在不需要的話用pass
* while語句
while b > 0:
   b--

* if-elif-else語句
注意,沒有C中的switch。
if x < 0:
   y = -x
elif x == 0:
   y = 0
else:
   y = x

* for語句
是在一個序列中迭代。
a = ['cat', 'dog', 'bird']
for x in a:
   print x, len(x)
注意在迭代的時候修改list很不安全,這時可以迭代它的一個備份,如:

>>> for x in a[:]: # make a slice copy of the entire list
...     if len(x) > 6: a.insert(0, x)
... 
>>> a
['defenestrate', 'cat', 'window', 'defenestrate']

如果要迭代下標,經常用range函數:
for i in range(len(a)):
   print i, a[i]

* break和continue
break和continue的用法一樣,但是從break退出和自然推出(for的元素迭代完畢; while的條件爲假)是
不一樣的。自然退出將執行else語句,這裏是一個很好的例子:
for n in range(2, 10):
   for x in range(2, n):
     if n % x == 0:
       print n, 'equals', x, '*', n/x
       break
     else:
       # loop fell through without finding a factor
       print n, 'is a prime number'



另一部分:



1. 函數定義
很簡單,就是
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

* docstring
注意第一行如果是字符串,則被看做函數的docstring,可以這樣查看
print fib.__doc__

* 返回值
什麼都可以,比如list. 如果不return將返回None,不帶參數的return也會返回None

* lambda函數
f = lambda x: x*x;
print f(5) # 25

* 缺省參數
必須在最前面。它們只被計算一次。例如
def f(a, L=[]):
     L.append(a)
     return L

print f(1)
print f(2)

將打印出
[1]
[1, 2]

模擬如下:
1. 計算缺省值[]:new一個新list(不妨稱它爲X)並賦值爲[]
2. f(1),L=X。注意賦值的是引用,因此L.append(a)實際上修改了X
3. f(2),L=X。注意這個時候X沒有重新初始化爲[],顯然這個時候X已經有一個元素1了...

如果希望每次打印出的都是[1],應該這樣寫:
def f(a, L=None):
     if L is None:
         L = []
     L.append(a)
     return L

2. 函數調用
* 關鍵字參數
規則:先位置參數,再關鍵字參數,且不能給一個參數指定多個值

* 位置參數列表
def fprintf(file, format, *args):
   file.write(format % args)
就把第三個參數開始的其他參數包裝成一個tuple
調用時,range(*[3,6])相當於range(3,6)

* 關鍵字參數集合
這裏有個和起來的例子
def fun(name, *arguments, **keywords):
     print "Hello", name, "!"

     # print arguments
     print "Arguments: "
     for arg in arguments: print arg
     keys = keywords.keys()
     keys.sort()

     # print keywords
     print "Keywords:"
     for kw in keys: print kw, ':', keywords[kw]

下面是一個調用的例子:
fun('srbga', 1, 'ok', [3,4,7], age=24, gender='male')
下面是另一種調用方式:
fun('srbga', *(1, 'ok', [3,4,7]), **{"age":24, "gender":'male'})

3. 作用域規則
與函數隨之而來的問題就是作用域規則。
函數在執行時將引入一個新的符號表。
* assignment. 一定保存在local
* reference. 先看local,再global,最後built-in.
要給global賦值必須用global語句。

函數調用時,實際參數總是放在local符號表中,它們總是對象引用。

4. 再談列表
* 常用函數:
append(x)/extend(L)             # 尾部添加
insert(i,x)/remove(x)/pop([i]) # 插入/刪除
index(x)/count(x)               # 查找/計數
sort()/reverse()                # 排序/反轉

* 常用數據結構
Stack. 用append()和不帶參數的pop()
Queue. 用append()和pop(0)

5. 用於list的FP方法
* 可以用filter篩選元素。
filter(lambda x:x%2!=0 and x%3!=0, range(2,25)) # [5, 7, 11, 13, 17, 19, 23]

* 可以用map進行映射。甚至可以是多個list的對應元素的運算。
map(lambda x:x*x*x, range(1,5))          # [1, 8, 27, 64]
map(lambda x,y:x+y, range(5), range(5)) # [0, 2, 4, 6, 8]

* 可以用reduce反覆對list的前兩個元素進行一個運算,直到變成一個元素。
reduce(lambda x,y:x+y, range(1,100))     # 1+2+...+99=4950
reduce(lambda x,y:x*y, range(1,10), 1)   # 10!=3628800

* 利用list comprehension可以構造出更爲簡單的程序
vec=[2,4,6]
[3*x for x in vec]            # [6, 12, 18]
[3*x for x in vec if x > 3]   # [12, 18]
[[x,x**2] for x in vec]       # [[2, 4], [4, 16], [6, 36]]
注意元組必須用括號,例如[x, x**2 for x in vec]是非法的。
甚至可以用二重循環,例如
vec1=[2,4,6]
vec2=[4,3,-9]
[x*y for x in vec1 for y in vec2]            # [8, 6, -18, 16, 12, -36, 24, 18, -54]
[vec1[i]*vec2[i] for i in range(len(vec1))] # [8, 12, -54]
還有一個有趣的例子:
[str(round(355/113.0, i)) for i in range(1,6)] # ['3.1', '3.14', '3.142', '3.1416', '3.14159']

6. 元組
元組最大的特點就是不可變。注意元素個數爲0或1的表示
empty=()
singleton=1,
另外,多重賦值是一個packing+unpacking的例子,其中packing的結果必須是元組,
而任何sequence都可以unpacking.

7. 集合
可以由序列創建集合,例如
seq=[1,2,3,1,2,4]
s1=set(seq)            # set([1,2,3,4])
s2=set([2,4,5])        # set([2,4,5])
1 in s1                # True
a-b                    # difference.            set([1,3])
a|b                    # union.                 set([1,2,3,4,5])
a&b                    # intersection.          set([2,4])
a^b                    # symmetric difference. set([1,3,5])

8. 字典
字典是關聯存儲器,用不可變對象做關鍵字,如number, string和tuple。
del b          # delete previously defined b
b={}           # now b is a mapping
a=[1,2]        # a is a list
b[a]=3         # invalid!
a=tuple(a)     # now tuple
b[a]=3         # this is ok
b              # {(1,2): 3}
b['ok']='yes'
b              # {(1,2):3, 'ok':'yes'}
b.keys()       # [(1,2), 'ok']
del b[a]
b              # {'ok':'yes'}
b.has_key(a)   # False

構造函數非常有用:
dict([(x, x**2) for x in (2, 4, 6)]) # {2:4, 4:16, 6:36}
dict(a=1,b=2)                         # {'a':1, 'b':2}

9. 枚舉
除了for x in s外還可以同時用到key和value,或者index和value,如
for k, v in some_dict.iteritems():
   print k, v
for i, v in enumerate(some_sequence):
   print i, v
還有一個經典的例子是:
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)

在for中可以用reversed()或者sorted()修飾。如果還需要去掉重複的話,可以
for f in sorted(set(seq)):
   print f

10. 條件
注意條件不見得是Boolean型。0和None是假,其他爲真。
* in / not in
* is / is not
* a < b == c
* A and not B or c 等價於 (A and (not B)) or c
* and和or是短路運算符,當用於其他類型的運算時,返回最後一個計算出來的表達式。例如
'a' or 'b' or 'c'           # 'a'
'' or '' or 'a' or 'b'      # 'a'
'a' and 'b' and 'c'         # 'c'
'a' and 'b' and '' and 'c' # ''
條件中不能有賦值,因此if a = 2: exit()是非法的

11. 比較
同類sequence的比較爲字典序比較,元素本身是序列時遞歸比較。
可以比較不同類的序列,結果按照type的字典序比較,因此list<string<tuple。數值型按照數值大小排序,因此0==0.0

12. 模塊
一個包含定義和語句的文件稱爲模塊(module),主文件名就是模塊名,在模塊內部用__name__表示。
import一個完成模塊將把該模塊本身引入到符號表中,例如
import sys
print sys.argv
而如果用from的話是直接把它的符號表中的一個或多個符號引入,例如
from sys import argv
print argv
這樣做有個潛在危險就是引入的符號和現有符號相沖突。甚至可以引入*(不包含以下劃線開始的符號)

模塊搜索路徑放在PYTHONPATH環境變量中,啓動後和其他一些系統相關的路徑混合後放在sys.path中。注意自定義模塊不要和系統模塊重名,不然很可能出錯。另外,關於編譯後的pyc和pyo,不會提高執行效率,只會減少啓動時間。它們是系統無關的,可以不依賴於.py而單獨存在。

可以用dir()來查看模塊的符號表,注意內置函數在__builtin__中。
import __builtin__
dir(__builtin__)

13. 包
有了模塊,你不必擔心你的程序中的變量和其他程序中的變量衝突;有的包,你不必擔心你的模塊名
和其他模塊名衝突。包的管理和Java類似,每個目錄中需要有一個__init__.py,import的時候最後一項
之前的必須都爲包名(最後一項可以是包名或者模塊名,但不能是符號名)


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章