这一章讲了Python的基本语法,从最最开始来讲到数据挖掘所需要的Python知识,可见Joel Grus的良苦用心,在这里最基本的语法就忽略掉了,从稍微有点奇妙的地方开始入手。
在python中,定义方法使用def
关键字。
def double(x):
return x*2
在Python中,方法可以当做变量来使用,如下:
def apply_to_one(f):
return f(1)
my_double = double
print apply_to_one(double) # 值为2
当然了,也可以使用匿名函数,使用lambda
关键字
apply_to_one(lambda x:x+4) # 返回5
方法也可以被给出默认值:
def my_print(message='hello'):
print message
my_print(message = '12345') #打印出12345
my_print() #打印出hello
当然了,也可以指定参数赋值。
def subtract(a=0, b=0):
return a - b
print subtract(10, 5) # 5
print subtract(0,5) # -5
print subtract(b=5) # -5
字符串可以使用单引号,也可以使用双引号。Python语法中也有转义字符:
tab_string = "\t"
print len(tab_string) # 值为1
当然了,如果我们不想用转义字符,我们可以使用r""
来定义原始字符串。
not_tab_string = r"\t"
print len(not_tab_string) #值为2
如果有多行字符串,我们使用triple-quotes
。
s = """sssss
afadsfasdfasd
dsfasdfasd"""
Python有异常机制:
try:
print 0/0
except ZeroDivisionError:
print "ZeroDivisionError"
Python列表有操作检测成员
1 in [1,2,3] # True
4 in [1,2,3] # False
列表可以很简单扩展:
x = [1,2,3]
x.extend([4,5,6])
print x # [1,2,3,4,5,6]
如果你不想改变x的值,可以这样:
x = [1,2,3]
y = x + [4,5,6]
有时候,我们不需要某些值,直接可以这样:
_, y = [1,2] # _就是我们不需要关心的值
元组与列表不同之处在于元组元素不可以被改变,在Python中很容易进行变量交换。
x, y = 1,2
x, y = y,x
字典是特别重要的一种数据结构。
empty_dict = {} #很好的做法
empty_dict2 = dict() #不太好的做法
grades = {'Joel':80,'Tim':95}
字典中直接通过键来得到对应的值。字典有一个方法当你没有找到键的时候,就会返回一个默认值。
joel_grade = grades.get('Joel',0) # 80
kate_grade = grades.get('kate',0) # 0
我们经常使用字典来作为一个结构数据:
tweet={
'user':'qwert',
'text':'adgfdag',
'sfdsd':['123','345','456']
}
print tweet.keys() #获取键
print tweet.values() #获取值
print tweet.items() #获取键值对
如果判断一个键是否在里面:
'user' in tweet
想象一下,你要统计一篇文档中单词的个数,很明显的做法就是建立一个字典,键为单词,值为个数。
document = 'I love my mom I love father haea I hava'
document = document.split(' ')
word_counts = {}
for word in document:
if word in word_counts:
word_counts[word] += 1
else:
word_counts[word] = 1
当然我们可以这样:
word_counts ={}
for word in document:
try:
word_counts[word] += 1
except KeyError:
word_counts[word] = 1
还可以这样:
word_counts ={}
for word in document:
previous_count = word_counts.get(word,0)
word_counts[word] = previous_count+1
在数值计算中,计数很常用。
from collections import Counter
c = Counter([0,1,2,0])
print c.items() # 返回[(0, 2), (1, 1), (2, 1)]
这样就很容易使用此方法来统计单词的个数了
c = Counter(document)
输出:
c = Counter(document)
for word,count in c.items():
print word,count
集合一个最重要的特性就是没有重复元素。
s = set()
s.add(1) 1
s.add(2) 2
s.add(2) 2
当判断一个元素是否在一个集合里面,最好使用set
。
slist = ['a','an','ann','e']
print 'an' in slist # 这是对的,但需要检查每一个元素
s = set(slist)
print 'an' in s # 更加快
我们一般使用if else
来作为控制语句。更一般的,我们可以使用:
p = 'even' if x%2==0 else 'odd'
x = [4,1,2,3]
y = sorted(x) # [1,2,3,4] 但是x没有改变
x.sort() # x改变了
一般的,sort
采用从小到大排序,如果你想从大到小排序,指定reverse=True
就可以了。还可以自定义排序。
x = sorted([-4,1,-2,3],key=abs,reverse=True) #[-4,3,-2,1] 根据绝对值的大小来排序。
wc = sorted(word_counts.items(), key=lambda (word,count):count,reverse=True) # 指定根据计数的大小排序。
在列表操作中,有通过生成式来得到列表:
even_numbers = [x for x in range(5) if x%2==0] #[0,2,4]
squares = [x*x for x in range(5)] # [0,1,4,9,16]
even_squares = [x*x for x in even_numbers] #[0,4,16]
也可以将列表改成字典:
squares_dict = {x:x*x for x in range(5)}
如果不关心里面的值,可以这样:
zeros = [0 for _ in even_numbers]
当然了,也可以使用多个for
。
pairs = [(x,y) for x in range(10) for y in range(10)]
列表操作是特别耗内存的,有时候还会超出内存。这时候我们使用迭代器,使用关键字yield。
def lazy_range(n):
i = 0
while i < n:
yield i
i += 1
for i in lazy_range(5):
print i
import random
four_uniform_randoms = [random.random() for _ in range(4)]
还可以生成定义区域空间内的随机数
random.randrange(10)
random.randrange(1,4)
可以打乱数字的位置:
up_to_ten = range(10)
random.shuffle(up_to_ten) #[5, 1, 2, 4, 3, 8, 7, 9, 6, 0]
如果你想在一个列表中随机选择一个元素,可以使用random.choice
。
my_best_friend = random.choice(['Alice','Tom','Charlie'])
如果你想选择一批不重复的数据,可以使用random.sample
。
lottery_numbers = range(50)
winning_numbers = random.sample(lottery_numbers,6) #[47, 0, 34, 27, 25, 37]
如果可以选择可以重复的数据,可以使用random.choice。
for_with_replacement = [random.choice(range(10)) for _ in range(4)]
import re
print not re.match("a","cat") #True
print re.search("a","cat") #True
print not re.search("c",'dog') #True
print re.split("[ab]","carbs") #3
print re.sub("[0-9]","-","R2D2") #R-D-
这本书中,为了说明面向对象的思想,做了一个set
集合的类,也算是帮助我们掌握面向对象思想吧。首先,集合可以添加元素,删除元素,判断一个元素是否在集合里面,并完成方法。
class Set(object):
"""docstring for Set"""
def __init__(self, values=None):
self.dict = {}
if values is not None:
for value in values:
self.add(value)
def __repr__(self):
return "Set:"+str(self.dict.keys())
def add(self, value):
self.dict[value] = True
def contains(self, value):
return value in self.dict
def remove(self, value):
del self.dict[value]
s = Set([1,2,3])
print s #Set:[1, 2, 3]
s.add(4)
print s.contains(4) #True
s.remove(3)
print s.contains(3) #False
python中的函数有很多功能,有map,reduce
和filter
.
def double(x):
return 2 * x
xs = [1,2,3,4]
twice_xs = [double(x) for x in xs] #[1,4,9,16]
twice_xs = map(double, xs) #同上
如果提供多个参数,也可以:
def multiply(x,y): return x * y
products = map(multiply, [1,2],[3,4])
print products #[3,8]
使用filter过滤:
def is_even(x): return x%2==0
x = range(10)
print filter(is_even, x)
还有:reduce
x_product = reduce(multiply,xs) #返回 1*2*3*4 = 24
在对列表进行遍历的时候,不要忘了enumerate
.可以同时得到下标和值。
s = [1,3,4,5]
for i,v in enumerate(s):
print i,v
list1 = ['a','b','c']
list2 = [1,2,3]
zip(list1,list2) #[('a', 1), ('b', 2), ('c', 3)]
也可以解析:
pairs = [('a', 1), ('b', 2), ('c', 3)]
letters, numbers = zip(*pairs)
def doubler(f):
def g(x):
return 2 * f(x)
return g
def f1(x):
return x+1
g = doubler(f1)
print g(3) # 8
还有一些参数表达式。
def magic(*args, **kwargs):
print args
print kwargs
magic(1,2,key="word",key2='word2') #(1, 2)
{'key2': 'word2', 'key': 'word'}
这里,args是一个元组类型,kwargs是一个字典数据类型。
def other_way_magic(x,y,z):
print x+y+z
x_y_list = [1,2]
z_dict = {'z':3}
other_way_magic(*x_y_list,**z_dict)
一个星号解析列表,2个星号解析字典。
到这里,这本书的Python基本语法介绍完了。