1. 选教程
看到crossin的编程教室python教程还不错。以这个为主要学习内容。
python简单实验的编辑器用IDLE已经足够,更好的网上有推荐PyCharm(又是JetBrain的产品)的。
2. 站队
python学习需要站队,有2.7版本有3.6版本。我选择优先3.6,因为语法感觉更规范,当然2系列的语法也必须看懂,要不然以前的很多成果无法使用的。
3. if语句,while语句都不是像C语言使用大括号来界定其后的block的,而是采用冒号和后面的代码缩进来实现的。
4. for的反人类写法
最反人类的写法是这个
for i in range(1,101):
print i
sum = sum + i
print sum
打印结果是1~100, 而不是1~101. 最后sum是5050. 内心疯狂了有木有,有木有。
5. 关于字符串
以下都是对的
print "It's good" 外面双引号里面就用单引号,反过来一样
print "It\'s good"
#同样支持转义字串
print "You are a \"good\" man"
超级无敌的三个引号,里面的内容原样显示,包括换行:
print """
Stay hungry,
stay foolish.
-- Steve Jobs
"""
再看几个字符串的例子,一看就懂
print "very "+ str1
print "price is %.2f" %4.99
yourname="Stephen"
print "I love you, %s." %yourname
print "Today is %s." %'Friday'
6. for的嵌套
看个例子
*
**
***
****
*****
代码实现:
for j in range(0,5):
for i in range(0,j+1):
print "*",
print ""
注意到上面的逗号是不换行,在python3里要写成print('*', end=' ')
另外看一个例子,参数有多个的
print "%s's score is %d" % ('Mike', 87)
7. 布尔型的微小的反人类设计
在python中,其他类型转成 bool 类型时,以下数值会被认为是False:
为0的数字,包括0,0.0
空字符串,包括'',""
表示空值的None
空集合,包括(),[],{}
其他的值都认为是True。
其实这个规则还好了,0是False而1是True是计算机界的传统。
None是python中的一个特殊值,表示什么都没有。感觉有点像Java中的null
8. 函数
先看简单的例子,很小白:
def sayHello():
print ("well, hello")
sayHello()
sayHello()
sayHello()
明白了吧,def是定义一个函数体
再来个带参数的
def plusint(num1, num2):
print (int(num1) + int(num2))
print ("please input n1")
n1 = input()
print ("please input n2")
n2 = input()
sum = plusint(n1,n2)
print (sum)
9. 条件if , else, elif
看下面的例子足够
print ("please input a")
a = input()
if a=="1":
print ("you input 1")
elif a=="2":
print ("you input 2")
else:
print ("you input other")
和其它语言一样, if也可以嵌套
10. 列表list
a = [1,1,2,3,5,8,13]
print (a)
b = range(10,15)
print (b)
c = ["meat","egg","fish"]
print (c)
d = [365, True]
print (d)
#delete second item in list c
del c[1] 注意这是删除指令,好熟悉,egg被删除了
for i in c:
print (i)
list中的每个元素都对应一个递增的序号。与现实中习惯的序号不同在于,计算机中的计数通常都是从0开始,python也不例外。如果你记不清这个而导致了错误,请去听一下孙燕姿的《爱从零开始》
#猜点球游戏,重点是choice方法的使用
from random import choice
print ("Choose one side to shoot:")
print ("left, center, right")
you = input()
print ("You kicked " + you)
direction = ["left", "center", "right"]
com = choice(direction) 从list中取出一个元素
print ("Computer saved" + com)
if you != com:
print ("Goal!")
else:
print ("Oops...")
另外关于list的负数表示,颠覆三观,实际是从右往左倒着数的意思:
>>> m = [1,3,5,7,9]
>>> m[-1]
9 倒数第1个元素是9
>>> m[-2]
7 倒数第2个元素是7
>>> m[2:4] 请注意,冒号这是切片操作符
[5, 7] 第2和第3个元素,从0计数
切片操作符是在[]内提供一对可选数字,用:分割。冒号前的数表示切片的开始位置,冒号后的数字表示切片到哪里结束。同样,计数从0开始。
注意,开始位置包含在切片中,而结束位置不包括。
11. 字符串的分割split
sentence1 = "I'm a student."
a1 = sentence1.split();
print (a1)
sentence2 = "3.1.4.1.5"
a2 = sentence2.split(".")
print (a2)
执行结果:
["I'm", 'a', 'student.']
['3', '1', '4', '1', '5']
12. 字符串的连接join
看例子就懂了
s=";"
t = ""
li = ["apple", "pear", "orange"]
fruit1 = s.join(li)
print (fruit1)
fruit2 = t.join(li)
print (fruit2)
执行结果:
apple;pear;orange
applepearorange
以上太费事了,简洁一点就这么写
result = "".join(['hello', 'world'])
结果是helloworld
13. 字符串运算总结:
1) 遍历
通过for...in可以遍历字符串中的每一个字符。
word = 'helloworld'
for c in word:
print c
2)索引访问
通过[]加索引的方式,访问字符串中的某个字符。
print word[0]
print word[-2]
与list不同的是,字符串不能通过索引访问去更改其中的字符。
word[1] = 'a'
这样的赋值是错误的。
3) 切片
通过两个参数,截取一段子串,具体规则和list相同。
print word[5:7]
print word[:-5]
print word[:] 全都打印出来了
4.)连接字符
join方法也可以对字符串使用,作用就是用连接符把字符串中的每个字符重新连接成一个新字符串。
newword = ','.join(word)
14. 文件读和写
#写文件例子
f1name = "1.txt"
f1 = open(f1name)
data = f1.read()
print (data)
f1.close()
#读文件例子
f2name = "2.txt"
f2 = open(f2name, "w")
f2.write("a new century");
f2.close()
readline() #读取一行内容
readlines() #把内容按行读取至一个list中
15. break和continue
while True:
a = input()
if a == 'hello':
print ("hello to you")
continue 继续循环
if a == 'bye':
break 中断
16. 异常
支持try: except:捕获异常
try:
f = open('non-exist222.txt')
print ('File opened!')
f.close()
except:
print ("maybe file not exist")
17. 字典(像是java里的map, key-value对)
score={
"Lucy":95,
"Lily":98
}
print (score)
del (score["Lucy"])
print (score)
18. 模块
import random 直接用import
print (random.randint(1,10))
print (random.choice([1,3,5]))
dir (random)
from math import pi 用from...import...
print(pi)
19. 方法的缺省参数
#def func(a=2,b)这是错误的,缺省的参数应该在最后
def func(a,b=5):
print (a+b)
func(3)
func(2,8)
20 综合例子 查天气
查天气就是发http request, 提交上城市的code, 然后返回json描述天气
import urllib.request
import json
from city import city 这里的city.py是一个字典,用于城市中文和城市代码对应关系的
def readweather():
cityname = input("which city?\n");
citycode = city.get(cityname)
#citycode = "101120201"
if citycode:
try:
url = ("http://www.weather.com.cn/data/cityinfo/%s.html" %citycode)
print ("url=\n" + url)
content = urllib.request.urlopen(url).read()
jsondata = json.loads(content) 看,这一句话就整成json了
print (content)
print ()
print (jsondata)
result = jsondata["weatherinfo"] 这一句话就把json节点取出来了
str_temp = ("weather is%s, and degree is:\nfrom %s to %s")%(
result["weather"], 把json的子节点取出来,这是天气概况
result["temp1"], 最低温度
result["temp2"] 最高温度
)
print (str_temp)
except:
print ("query fail") 可能网络服务异常或没网
else:
print ("city not found!") 没有找到合适的city
另外附上几行city.py内容:
city = {
'北京': '101010100',
'海淀': '101010200',
}
运行结果是这样的:
21. 面向对象
同样python支持OOP,看来简单的例子
class MyClass:
name = "Tom"
def sayHi(self): 这个self是个保留字,等同于java里的this. 是要显式的传递的,和java不一样的, 其实有点繁琐,
print ("Hi %s"%self.name)
def sayGoodbye(self, something):
print ("Goodbye %s"%something);
mc = MyClass()
mc.name="Lily"
mc.sayHi()
mc.sayGoodbye("now")
注意:
__init__函数会在类被创建的时候自动调用,用来初始化类
22. and和or的技巧
好吧,我讨厌这些技巧,看一眼知道意思就行了。
and-or真正的技巧在于,确保a的值不会为假。最常用的方式是使 a 成为 [a] 、 b 成为 [b],然后使用返回值列表的第一个元素:
a = "123"
b = "hell"
c = (True and [a] or [b])[0]
print (c)
打印的是123
抛开绕人的and和or的逻辑,你只需记住,在一个bool and a or b语句中,当bool条件为真时,结果是a;当bool条件为假时,结果是b。
有学过c/c++的同学应该会发现,这和bool?a:b表达式很像。
我还是讨厌这种让人看不懂的用法
23. 元组(tuple)
其实 tuple(音:它跑)也译作数组
元组(tuple)也是一种序列,和我们用了很多次的list类似,只是元组中的元素在创建之后就不能被修改。---好吧,我可以把它当作list常量吗?
position = (1, 2)
geeks = ('Sheldon', 'Leonard', 'Rajesh', 'Howard')
print (position)
print (geeks)
#都是元组的实例。它有和list同样的索引、切片、遍历等操作
上面讲的太高深和不接地气了,其实:
其实我们之前一直在用元组,就是在print语句中:
print '%s is %d years old' % ('Mike', 23)
('Mike', 23)就是一个元组。这是元组最常见的用处。
23. math库
和其它语言一样,提供了许多的数学库,千万要用,不要自己再发明轮子了
import math
print ("pi="+ str(math.pi))
print ("e="+ str(math.e))
print ("2^32=" + str( math.pow(2,64) ) )
print ("sqrt " + str ( math.sqrt(2) ))
24. 正则表达式
import re
text = "Hi, I am Lucy"
m = re.findall(r"[Hh]i", text)
if m:
print (m)
else:
print ("not match")
结果输出['Hi']
r"hi"
这里字符串前面加了r,是raw的意思,即不使用转义
今天主要说两个符号“.”和“*”,顺带说下“\S”和“?”。
“.”在正则表达式中表示除换行符以外的任意字符。在上节课提供的那段例子文本中:
Hi, I am Shirley Hilton. I am his wife.
如果我们用“i.”去匹配,就会得到
['i,', 'ir', 'il', 'is', 'if']
你若是暴力一点,也可以直接用“.”去匹配,看看会得到什么。
与“.”类似的一个符号是“\S”,它表示的是不是空白符的任意字符。注意是大写字符S。
--
在很多搜索中,会用“?”表示任意一个字符,“*”表示任意数量连续字符,这种被称为通配符。但在正则表达式中,任意字符是用“.”表示,而“*”则不是表示字符,而是表示数量:它表示前面的字符可以重复任意多次(包括0次),只要满足这样的条件,都会被表达式匹配上。
结合前面的“.*”,用“I.*e”去匹配,想一下会得到什么结果?
['I am Shirley Hilton. I am his wife']
结果是['ley Hilton. I am his wife'],即贪婪匹配
再換成这个"l.*?e", 懒惰匹配,得到['le', 'lton. I am his wife']
这里不说太多了,记不住,做爬虫实战的时候,一定会返回来继续看的。
25. 再议随机数
1)产生随机整数
num = random.randint(1,100)
2)产生随机小数,
num2 = random.uniform(5,6.5)
print (num2)
2)关于choice
random.choice(seq)
从序列中随机选取一个元素。seq需要是一个序列,比如list、元组、字符串。
random.choice([1, 2, 3, 5, 8, 13]) #list
random.choice('hello') #字符串
random.choice(['hello', 'world']) #字符串组成的list
random.choice((1, 2, 3)) #元组
3) 带step的高级用法
random.randrange(start, stop, step)
random.randrange(1, 9, 2)
就是从[1, 3, 5, 7]中随机选取一个。
random.randrange(start, stop, step)其实在效果上等同于
random.choice(range(start, stop, step))
4)取样
random.sample(population, k)
从population序列中,随机获取k个元素,生成一个新序列。sample不改变原来序列
26. 关于时间time
import time
starttime = time.time() 一个很大的小数
print (starttime)
time.sleep(2) 延时2秒
print ("2 secs arrived")
27. 调试程序
traceback信息就是报错,也可以自己在合适的地方print
28. python shell的使用
提示符>>>就不再提了,关注一下返回上一个命令不是像DOS命令行一样按上箭头,而是alt+p 组合
29. 序列化pickle
存到文件和从文件中取出
import pickle
test_data = ["save me!", 123.456, True]
f = open("mypickle.txt", "wb")
pickle.dump(test_data, f)
f.close()
f2 = open("mypickle.txt", "rb")
newdata = pickle.load(f2)
f2.close()
print (newdata)
运行结果是:
['save me!', 123.456, True]
30. 列表解析List Comprehension
让代码更简洁的办法:
list_1 = [1, 2, 3, 5, 8, 13, 22]
list_2 = [i for i in list_1 if i % 2 == 0]
print list_2
输出
[2, 8, 22]
31. 带参数的函数
光看例子不说话,体会一下
def func(arg1=1, arg2=2, arg3=3):
print arg1, arg2, arg3
调用
func(2, 3, 4)
func(5, 6)
func(7)
输出为
2 3 4
5 6 3
7 2 3
好了,你一定秒懂。
上次说的 func(*args) 方式是把参数作为 tuple 传入函数内部。而 func(**kargs) 则是把参数以键值对字典的形式传入。
示例:
def printAll(**kargs):
for k in kargs:
print k, ':', kargs[k]
printAll(a=1, b=2, c=3)
printAll(x=4, y=5)
输出:
a : 1
c : 3
b : 2
y : 5
x : 4
在混合使用时,首先要注意函数的写法,必须遵守:
带有默认值的形参(arg=)须在无默认值的形参(arg)之后;
元组参数(*args)须在带有默认值的形参(arg=)之后;
字典参数(**kargs)须在元组参数(*args)之后。
32. 兰布达表达式
来看一个复杂一点的例子,把 lambda 表达式用在 def 函数定义中:
def fn(x):
return lambda y: x + y
a = fn(2)
print a(3)
输出:
5
这里,fn 函数的返回值是一个 lambda 表达式,也就等于是一个函数对象。当以参数2来调用 fn 时,得到的结果就是:
lambda y: 2 + y
33. 变量的作用域
def func(x):
print ("X in the beginning of func(x):", x)
x = 2
print ("X in the end of func(x):", x)
x = 50
func(x)
print ("X after calling func(x): ", x)
print()
def func2():
global x
#建议在写代码的过程中,显式地通过 global 来使用全局变量,避免在函数中直接使用外部变量。
print ("X start func(x):", x)
x = 3
print ("X end func(x):",x)
func2()
运行结果
X in the beginning of func(x): 50
X in the end of func(x): 2
X after calling func(x): 50
X start func(x): 50
X end func(x): 3
34. 使用map
map()的使用方法形如map(f(x),Itera).
def triple_func(x):
return x * 3
#lst_2 = list( map(triple_func, lst_1) )
lst_2 = list( map(lambda x: x*3, lst_1) )
print (lst_2)
35. 使用reduce
reduce()的使用
reduce()的使用方法形如reduce(f(x),Itera).对,它的形式和map()函数一样。不过参数f(x)必须有两个参数。reduce()函数作用是:把结果继续和序列的下一个元素做累积计算。
from functools import reduce
lst = range(1, 101)
def add(x, y):
return x + y
print (reduce(add, lst))
36. 多线程
暂不学了