1 美观并正确地书写Python语句

书写的美观性

往往问题不仅是美观,还在于程序的可读性:


In [1]:
testnum = True
print testnum
testnum = True;print testnum


True
True

书写的正确性

用四空格或一Tab表示缩进。

错误缩进:


In [1]:
i = 42
    print "Value is ,{0}".format(i)


  File "<ipython-input-1-ca4e5ad1bc31>", line 2
    print "Value is ,{0}".format(i)
    ^
IndentationError: unexpected indent

正确缩进:


In [6]:
for i in xrange(5):
    if i > 3:
        break
    else:
        print i,
else:
    print "Expectedly Finished"


0 1 2 3

2 Python控制流语法(if/else/for/while等)

2.1 if和else

在Python中,标准的if-else或者单if条件语句语法是这样的:


In [2]:
expression = True

if expression:
    print "do something"
else:
    print "do something_else"


do something

程序员笑话:


In [8]:
hot = True
watermelon = True
cnt_steamdumpling = 12
if hot & watermelon:
    cnt_steamdumpling = 1

print cnt_steamdumpling


1

运算符有优先级:


In [3]:
yourage = 25
had_a_girlfriend = False

if yourage > 18 and not had_a_girlfriend:
    print "Damn..."
else:
    print "Ok."


Damn...

多重if-else使用elif:


In [4]:
your_salary = 7000
your_location = "Beijing"
if your_salary > 100000:
    print "( ̄︶ ̄)> []"
elif your_salary >= 25000:
    print "<( ̄︶ ̄)/*"
else:
    print "( ̄﹏ ̄) ( ̄ˇ ̄)"


( ̄﹏ ̄) ( ̄ˇ ̄)

书写if else 语句时候也是另一个需要注意缩进的地方

如果你在Ipython中书写if-else语句的话,Ipython将在“:”的下一行自动为你缩进,这点非常方便,但是不推荐以下风格的代码:


In [11]:
if True: print "do something"


do something

2.2 条件表达式(三元操作符)

正常的if/else写法,有些臃肿


In [6]:
x,y = 111,17
if x < y:
    smaller = x
else:
    smaller = y
print smaller


17

简洁的三元表达式,Ruby风味


In [8]:
x , y = 25,10
smaller = x if x < y else y
print smaller


10

短路求值写法:


In [9]:
x , y  = 3 , 5
smaller =  x < y and x or y # x = a?b:c None,'',0,False
print smaller

x , y  = 5 , 3
smaller =  x < y and x or y
print smaller


3
3

装X失败案例:x被判False


In [17]:
x , y  = None , 0

print x < y

smaller =  x > y and x or y
print smaller


True
0

2.3 For循环

先介绍range(start,end,step)函数:(生成可迭代序列,Iterable)


In [22]:
print range(10)
print range(1,5,1)
print range(5,1,-1)
print xrange(10)
for i in xrange(10):
    print i ** 2,


[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[1, 2, 3, 4]
[5, 4, 3, 2]
xrange(10)
0 1 4 9 16 25 36 49 64 81

In [24]:
s = "string"

for循环可以方便的迭代字符串


In [25]:
for eachletter in s:
    print eachletter


s
t
r
i
n
g

Python 默认会在每个打印出来的字母后加换行符。

如果不需要这个特性,则在语句后加逗号“,”:


In [26]:
for eachletter in s:
    print eachletter,


s t r i n g

同步取循环索引

回忆一下基础语法中介绍的len函数和字符串的切片访问方法,不推荐以下写法:


In [6]:
a = "Be Enumerated"
lena = len(a)
print lena
print range(lena)
for eachnum in range(lena):
    print "{0} {1:>2}".format(a[eachnum],eachnum)


13
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
B  0
e  1
   2
E  3
n  4
u  5
m  6
e  7
r  8
a  9
t 10
e 11
d 12

用enumerate方法来同步循环索引:


In [7]:
for idx, element in enumerate(a):
    if idx%2==0 or element=='e':
        print idx, element


0 B
1 e
2  
4 n
6 m
7 e
8 r
10 t
11 e
12 d

2.4 while语法和奇特的else

while语句的形式类似if语句。

如果while后面的条件为真,冒号下的代码块就会不断循环执行,直到判断条件变为0或者False.

while语句后可以写else语句,如果没被干涉,最终收尾的时候会执行代码。


In [8]:
count = 0
while count <= 3:
    print "looping {0}".format(count)
    count += 1
    print count
else:
    print "Finite loop"

count = 0
while True:
    print "looping {0}".format(count)
    count += 1
    print count
    if count > 3:
        break
else:
    print "Broken loop"


looping 0
1
looping 1
2
looping 2
3
looping 3
4
Finite loop
looping 0
1
looping 1
2
looping 2
3
looping 3
4

while-else的组合有些奇特,补充一个更奇特的组合:for-else。


In [9]:
for i in xrange(3):
    print i
else:
    print "Finished"

print "=" * 20

for i in xrange(3):
    if i > 1:
        break
    print i
else:
    print "Finished"


0
1
2
Finished
====================
0
1

2.5 干涉循环行为(break/continue/pass)

  • pass:不做任何事。
  • continue:告诉 Python 跳过当前循环块中的剩余语句,继续进行下一轮循环。
  • break:结束当前循环来跳转到下个语句。

这三个语句有时和if语句一块搭配使用。


In [10]:
def foo():
    pass

a = [1, 0, 2, 4]
for element in a:
    if element == 0:
        continue
    print 1. / element


1.0
0.5
0.25

In [19]:
z = 1 + 1j
while True:
    if abs(z) > 100:
        break
    z = z ** 2 + 1
    print z


(1+2j)
(-2+4j)
(-11-16j)
(-134+352j)

3 Python基本数据结构详述

Python中内置了四种数据结构—列表,元组,字典和集合,用三种不同的括号就可以表示他们。

list(列表)是处理一组有序项目的数据结构,列表的元素需要以[](中括号)来包裹,元素的个数和值可以改变。

tuple的元素以() 来包裹,元组可以看作只读的列表。

列表和元组都使用切片方法来访问元素,数字索引从0开始计数。

通过切片([]和[:]),列表和元组可以得到子集。列表的子集是列表,元组切片后结果还是元组(不可改变)。

3.1 List 列表(可变类型)

列表的定义可以直接使用方括号扩住数据。

熟悉的切片规则[start,end,step]:


In [23]:
L = ['red','blue','green','black','white']
print isinstance(L,list)
print L[0],L[-1]
print L[2:4]
print L[:3],L[::2]


True
red white
['green', 'black']
['red', 'blue', 'green'] ['red', 'green', 'white']

作为可变类型中的一种,列表可以直接修改:


In [35]:
M = ['red','blue','green','black','white',42,True]  # 列表中可以包含不同类型的元素
M[2:4] = ['Ruby','sapphire']
N = M
print id(M),id(N)
M[-1] = False                                     # 可以通过切片修改
print N                                           # 可变类型的特点,不直接操作N,N内容被改变


4371170728 4371170728
['red', 'blue', 'Ruby', 'sapphire', 'white', 42, False]

In [40]:
import numpy as np
a = np.array(range(10))
print a,type(a),a.dtype
import scipy as sp
import statsmodels as smodel
import pandas as pd


[0 1 2 3 4 5 6 7 8 9] <type 'numpy.ndarray'> int64

对于同一类型的数值数据,推荐使用运行效率更高的numpy来进行处理。

对于列表,我们可以使用多种方法来进行操纵:


In [42]:
LM = ['red','blue','green','black','white']
print LM
LM.append('pink')
print LM # 列表尾部添加一个元素
popped = LM.pop()# 删除并返回列表最后一个元素
print LM,popped
#试试LM.pop(0)
popped2 = LM.pop(0)
print LM,popped2
LM.extend(['pink','purple','purple'])       # 讲extend后的序列添加到列表中,extend后的内容应该是可迭代的
print LM
LM.remove('purple')                       # 删除指定值的一个元素
print LM
print popped


['red', 'blue', 'green', 'black', 'white']
['red', 'blue', 'green', 'black', 'white', 'pink']
['red', 'blue', 'green', 'black', 'white'] pink
['blue', 'green', 'black', 'white'] red
['blue', 'green', 'black', 'white', 'pink', 'purple', 'purple']
['blue', 'green', 'black', 'white', 'pink', 'purple']
pink

In [44]:
print LM[::-1]
LL = LM.reverse   #此时已经调用完原地翻转列表方法
LL()
print LL
print LM
print LM*2       #也可以像字符串一样用*方法
print LM+LM      #也可以像字符串一样用+方法,但+方法不能直接增加元素。


['blue', 'green', 'black', 'white', 'pink', 'purple']
<built-in method reverse of list object at 0x1083ca320>
['blue', 'green', 'black', 'white', 'pink', 'purple']
['blue', 'green', 'black', 'white', 'pink', 'purple', 'blue', 'green', 'black', 'white', 'pink', 'purple']
['blue', 'green', 'black', 'white', 'pink', 'purple', 'blue', 'green', 'black', 'white', 'pink', 'purple']

In [46]:
#LL_law = M.sor
#M.sort()
#print M
#print LL_law
print M
Mnew = sorted(M)
print M
M.sort()
print M


['red', 'blue', 'Ruby', 'sapphire', 'white', 42, False]
[False, 42, 'Ruby', 'blue', 'red', 'sapphire', 'white']
['red', 'blue', 'Ruby', 'sapphire', 'white', 42, False]
[False, 42, 'Ruby', 'blue', 'red', 'sapphire', 'white']

判断某个元素是否在列表中,可以使用in 方法


In [28]:
LL_law = ['red', 'blue', 'Ruby', 'sapphire', 'white', 42, False]
my_precious = "silmarils"
print my_precious in LL_law
if "Ruby" in LL_law:
    print "Ok"


False
Ok

不爽字符串很久了?


In [30]:
string = 'Mukatsuku'
ls_str = list(string)
print ls_str
print ''.join(ls_str)


['M', 'u', 'k', 'a', 't', 's', 'u', 'k', 'u']
Mukatsuku

3.2 Tuple 元组(不可变类型)

元组的元素之间以逗号隔开,可以用小括号包裹(推荐):


In [49]:
war3 = ('Orc','Humans','Undead','Night Elves')
heros = 'Blade Master','Farseer','Tauren Chieftain','Shadow Hunter'

print type(war3),type(heros)


<type 'tuple'> <type 'tuple'>

如果需要明确地删除一个列表或者元组,使用del:


In [50]:
war3copy = war3
print war3copy


('Orc', 'Humans', 'Undead', 'Night Elves')

In [51]:
print war3copy[1]
war3copy[1]="Trans_Humans"


Humans
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-51-39c69d1512f2> in <module>()
      1 print war3copy[1]
----> 2 war3copy[1]="Trans_Humans"

TypeError: 'tuple' object does not support item assignment

和列表类似,元组同样支持+、*、和 in 方法。

折衷方案使用“可变”元组:


In [12]:
t = (42,False,[True],-203+1j)
t[2][0] = False
print t
print list(t)


(42, False, [False], (-203+1j))
[42, False, [False], (-203+1j)]

3.3 Set 集合(可变类型)与Frozenset 冻结集合(不可变类型)

用花括号来定义,用集合操作来进行运算,用set或者frozenset转化其他序列。


In [40]:
war3 = ('Orcs','Humans','Undead','Night Elves')
Lord_of_ring = ('Ainur','Dragons','Dwarves','Elves','Ents','Hobbits','Humans','Orcs')
test_set = set(war3)
train = set(Lord_of_ring)
ya_test_set = {'Orcs','Humans','Undead','Night Elves'}
print 'Orcs' in test_set
print 'Orcs' in train
print 'Orcs' in ya_test_set


True
True
True

对于单个集合内的操作对set而言很方便:


In [41]:
test_set.add('Xmen')
print test_set
test_set.update(['No.16','No.17','No.18'])
print test_set
for item in ['Xmen','No.16','No.17','No.18']:
    test_set.remove(item)
print test_set


set(['Xmen', 'Undead', 'Humans', 'Orcs', 'Night Elves'])
set(['Undead', 'No.17', 'No.16', 'No.18', 'Humans', 'Orcs', 'Night Elves', 'Xmen'])
set(['Undead', 'Humans', 'Orcs', 'Night Elves'])

不可变类型frozenset:


In [13]:
ftest = frozenset(test_set)
print ftest
ftest.add('Xmen')


---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-13-14a6fa50a9f5> in <module>()
----> 1 ftest = frozenset(test_set)
      2 print ftest
      3 ftest.add('Xmen')

NameError: name 'test_set' is not defined

集合之间的所有基本操作,对于set和frozenset都适用。

我们来验证两个集合论公式:

$A \hat{} B = (A \backslash B) \cup (B \backslash A)$

$A \hat{} B = (A \cup B) \backslash ( A \cap B)$


In [36]:
print test_set==train   #判断是否相等
print test_set<train    #判断是否是子集
print test_set>train    #判断是否是超集
print test_set&train    #求交集
print test_set|train    #求并集
print train-test_set    #求差集
print test_set^train    #求异或

print test_set^train == ((train-test_set) | (test_set-train))
print test_set^train == (train | test_set) - (train & test_set)


False
False
False
set(['Humans', 'Orcs'])
set(['Undead', 'Hobbits', 'Dwarves', 'Humans', 'Orcs', 'Night Elves', 'Dragons', 'Ents', 'Ainur', 'Elves'])
set(['Hobbits', 'Dwarves', 'Dragons', 'Ents', 'Ainur', 'Elves'])
set(['Undead', 'Hobbits', 'Dwarves', 'Night Elves', 'Dragons', 'Ents', 'Ainur', 'Elves'])
True
True

3.4 Dict 字典(可变数据类型)

花括号扩起来,形如{key1:value1,key2:value2,key3:value3}。

key是非重复的,value和key一一对应,不需要非重复。


In [14]:
language={"Scala":"Martin Odersky","Clojure":"Richy Hickey",\
          "C":"Dennis Ritchie","Standard ML":"Robin Milner"}
print language.keys()      #取得键
print language.values()    #取得值
print language.items()     #取得键-值对
print language.iterkeys()  #取得上述内容的iterable
print language.itervalues()
print language.iteritems()


['Standard ML', 'C', 'Clojure', 'Scala']
['Robin Milner', 'Dennis Ritchie', 'Richy Hickey', 'Martin Odersky']
[('Standard ML', 'Robin Milner'), ('C', 'Dennis Ritchie'), ('Clojure', 'Richy Hickey'), ('Scala', 'Martin Odersky')]
<dictionary-keyiterator object at 0x104891c58>
<dictionary-valueiterator object at 0x104891c58>
<dictionary-itemiterator object at 0x104891c58>

取得某个键对应的值,或者增加一个键值对:


In [54]:
print language['Standard ML']  
language["Python"]="Guido van Rossum" 
print language['Python']


Robin Milner
Guido van Rossum

试验一下迭代器:


In [49]:
for key in language:
    print 'key={0},value={1}'.format(key,language[key])


key=Python,value=Guido van Rossum
key=Standard ML,value=Robin Milner
key=C,value=Dennis Ritchie
key=Clojure,value=Richy Hickey
key=Scala,value=Martin Odersky

如果要访问某个键,而字典中又不存在这个键和对应的值,将会报错:


In [15]:
print language["Ruby"]


---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-15-2c7ef4b9ad9c> in <module>()
----> 1 print language["Ruby"]

KeyError: 'Ruby'

所以使用键之前可以先判断其是否在字典中然后再取:


In [52]:
print  language.has_key('Scala')
print 'Ruby' in language


True
False

或者使用一个非常有用的方法:dict.get(key,default=None)


In [55]:
print language.get("Haskell","They hardly understand IT")
print language.get("Python",None)


They hardly understand IT
Guido van Rossum

如果需要删除字典中的某些键 使用del somedict[some_key];

需要直接删除字典本身使用 del somedict即可。

向字典中添加键值对,或者根据键更新值非常方便:


In [56]:
language["Ruby"] = "Matz"
print language["Ruby"] + " is a short form, renew it."
language["Ruby"] = "Yukihiro Matsumoto"
print language["Ruby"] + " is the full name of Ruby's Creator."


Matz is a short form, renew it.
Yukihiro Matsumoto is the full name of Ruby's Creator.

In [ ]:


In [ ]:


In [ ]: