自学python入门笔记 2018-9-14 16:14:18

python第三版相比较第二版的差异:

  1. 打开文件不再支持file方法,只能用open
  2. range不再返回列表,而是一个可迭代的range对象
  3. 除法‘/’不再是整数,而是得到浮点数,整数需要用‘//’

学到的知识可以用来干嘛(以下以爬虫为例)!

  • list,dict:用来序列化你爬的东西
  • 切片:用来对爬取的内容进行分割,生成
  • 条件判断(if等):用来解决爬虫过程中哪些要哪些不要的问题
  • 循环和迭代(for while ):用来循环,重复爬虫动作
  • 文件读写操作(open,close等):用来读取参数、保存爬下来的内容等
  • 编码常识(codecs等):非常关键,爬虫写熟了以后遇到的各种古怪问题,很多来自于UTF-8 GBK等奇奇怪怪的编码!这个问题先做了解,后面调试时候再解决也不迟!

python基本指令:

  • input 输入
  • output 输出
  • math 计算
  • conditional execution 条件执行
  • repetition 重复

数据类型:

  • integers 整型
  • floats浮点型
  • booleans布尔值
  • strings字符串

variable and value 变量和值:

在python程序中,变量是用一个变量名表示,变量名必须是大小写英文/数字和下划线下划线(_)的组合,且不能用数字开头:

a=1   //变量’a‘是一个整数 int型
t_007 = 'T007' //变量t_007是一个字符串

在python中,等号=是赋值语句,可以把任意数据类型赋值给变量,同一个变量可以反复赋值,而且可以是不同类型的变量

speed_of_liuxiang=1000/13  //定义一个变量名为speed_of_liuxiang,并为这个变量赋值1000/13
distance=1000 
time=distance/speed_of_liuxiang 
print(time)
print(time/13)

math //数学公式

import math
Print(math.pi)
Print(math.e)

Print(math.floor(98.6)) 
98
Print(math.ceil(98.6))
99

可以用来运算数学公式,python手册搜math
b=10
r=1
n=100
b*((1+r/100)**n)
print(b)

字符串

字符串可以用''或者""括起来表示。

s="he said,\"i'm a boy\"" //变量s的值为he said,\"i'm a boy\" 是字符串
print(s) //输出结果为he said,"i'm a boy"

反斜杠,转义字符

如果字符串既包含'又包含"怎么办?

这个时候,就需要对字符串的某些特殊字符进行“转义”,Python字符串用\进行转义

换行 在字符串内输入 /n 或者 三个引号,如下:

s='''
first
second
'''
print(s)

type conversions 变量类型转换

print(str('1089')+'10')
输出结果:108910

print(1089+int('10'))
输出结果:1099

one_var='10'
s=1+int(one_var)
print(s)
输出结果:11


a='老柴是'
b='猪头'
c=a+''+b+'!!!'
print(c)
//please Guess the output?

Python 3可以做很大数的运算 没有上下限

Extract 字符串提取,可以按位去取

取字符串内的第一个字符(从0开始);

letters='asdfghjkliuytrew'
print(letters[0])
输出结果为:a

倒数第一个(从-1开始):

letters='asdfghjkliuytrew'
print(letters[-1])
输出结果为:w

取某一段字符串(start:end),从左向右去取的

letters='asdfghjkliuytrew'
print(letters[2:]) //包括2在内直到结束的全部字符串
输出结果:dfghjkliuytrew

按步长去取,[1:5:2]从第一个到第五个字符,每两个取一个

letters='asdfghjkliuytrew'
print(letters[1:5:2])
输出结果:sf

使用len 来取字符串的长度

letters='asdfghjkliuytrew'
print(len(letters))
输出结果为:16

切分字符串,.split方法

letters="asd fghjk liuy trew"
print(letters.split( ))
输出结果:['asd', 'fghjk', 'liuy', 'trew']

把切分的字符合并到一起。 ‘分隔符’

print(' '.join(['asd' 'fghjk' 'liuy' 'trew']))
输出结果:asdfghjkliuytrew

字符串替换:.replace方法

letters='asdfghjkliuytrew'
print(letters.replace('a','1’))
输出结果:1sdfghjkliuytrew

只替换n个字符,比如只想替换一个a 那么代码就是:

letters='asdfghjkliuytrew'
print(letters.replace('a',’1’,1))   最后的数字1代表只替换一次,替换第一个字符之后就不再替换了

输出格式:居中/巨左/居右等,还没有学习

其他函数,使用过程中想要达到什么功能,可以去python官网搜索手册

  • startswich //字符串开始
  • endswich //字符串结尾
  • fing //找某一个位置的字符
  • len //字符串长度

list和tuple类型

Python内置的一种数据类型是列表:list。list是一种有序的集合,可以随时添加和删除其中的元素。 构造list非常简单,直接用 [ ] 把list的所有元素都括起来,就是一个list对象。通常,我们会把list赋值给一个变量,这样,就可以通过变量来引用list

班里有3名同学:Adam,Lisa和Bart,他们的成绩分别是 95.5,85 和 59,请按照 名字, 分数, 名字, 分数... 的顺序按照分数从高到低用一个list表示

L = ['adam', 95.5, 'lisa', 85, 'bart', 59]
print (L)

按照索引访问list与倒序访问list

L = [95.5,85,59]
print L[0]  //访问L内的第0个元素,输出结果为95.5
print L[1]  //访问L内的第1个元素,输出结果为85  
print L[2]  //访问L内的第2个元素,输出结果为59
print L[-1]  //访问L内的倒数第1个元素,输出结果为59
print L[-2]  //访问L内的倒数第2个元素,输出结果为85 
print L[-3]  //访问L内的倒数第3个元素,输出结果为95.5

list添加新元素

1. append()方法

l=['a','b','c']
l.append('w')
print(l)   //输出结果为['a','b','c','w']

append()方法是把元素加到list最后面,如果想将元素添加到list内的其他位置,可用insert() 方法

2.insert()方法

l=['a','b','c']
l.insert(0,'q')
print(l)  //输出结果为['q','a','b','c']

l.insert(0,'q')的意思是将‘q’添加到索引位置为0的位置上,原来索引位置为0以及后面的元素都往后挪一挪

list删除

pop()方法

l=['a','b','c']
l.pop(0)
print(l)  //删除list内索引位置为0的元素

list 替换元素

l=['a','b','c'] l[0]=j //直接替换 将l内索引位置为0的元素替换为j print(l)

tuple

tuple是另一种有序的列表,中文翻译为“ 元组 ”。tuple 和 list 非常类似,但是,tuple一旦创建完毕,就不能修改了。

l=('a','b','c')

创建tuple和创建list唯一不同之处是用( )替代了[ ],现在这个tuple l就完全不能改变了,无论是添加/替换和删除都不行。

单元素tuple

包含0个元素的tuple,也就是空tuple

t=()
print(t) //输出结果为 ()

创建包含1个元素的tuple

t=(1)
print(t)// 输出结果为1  

为什么输出结果不是一个tuple 而是整数1呢 因为()既可以表示tuple,又可以作为括号表示运算时的优先级,结果 (1) 被Python解释器计算出结果 1,导致我们得到的不是tuple,而是整数 1 正是因为用()定义单元素的tuple有歧义,所以 Python 规定,单元素 tuple 要多加一个逗号“,”,这样就避免了歧义:

t=(1,)
print(t)// 输出结果为(1,)  

In and out输入和输出

passed_seconds=int(input('现在相对于凌晨已经过去多少分钟啦?'))
now_hour=(passed_seconds//60)
now_second=(passed_seconds%60)
print("哦我知道了~那么现在的时间就是:",now_hour,":",now_second)

字符串内有多少个字符

test_python='a a a a a a a'
print(test_python.count('a’))

将被*包裹的字符串输出

test_python='* a a a a a a a *'
print(test_python.strip('*’))

小练习:提取一些LOL官网上的英雄头像和名称等信息

s = [
  '<li><a href="info-defail.shtml?id=Aatrox" title="暗裔剑魔 亚托克斯"><img src="http://ossweb-img.qq.com/images/lol/img/champion/Aatrox.png" alt="暗裔剑魔 亚托克斯"><p>暗裔剑魔</p><span class="sbg"><i class="commspr commico-search"></i></span></a></li>',
  '<li><a href="info-defail.shtml?id=Ahri" title="九尾妖狐 阿狸"><img src="http://ossweb-img.qq.com/images/lol/img/champion/Ahri.png" alt="九尾妖狐 阿狸"><p>九尾妖狐</p><span class="sbg"><i class="commspr commico-search"></i></span></a></li>',
  '<li><a href="info-defail.shtml?id=Lux" title="光辉女郎 拉克丝"><img src="http://ossweb-img.qq.com/images/lol/img/champion/Lux.png" alt="光辉女郎 拉克丝"><p>光辉女郎</p><span class="sbg"><i class="commspr commico-search"></i></span></a></li>'
]

def hero_img (item):
  start = item.find('title=\"')
  start_name = item.find('\"', start)
  end_name = item.find('\"', start_name + 1)
  
  start2 = item.find('src=\"')
  start_link = item.find('\"', start2)
  end_link = item.find('\"', start_link + 1)

  print('英雄的名字是' + item[start_name + 1 : end_name] + ', 他的头像地址是:' + item[start_link + 1 : end_link])
for hero in s:
  hero_img(hero)

break 退出循环

计算1+2+4+8+。。+16+。。+20的和

sum = 0  //定义总和这个变量
x = 1      //每次加的数的数值
n = 1 //已经加了多少个数
while True:
if n>20:
break
sum=sum+x //计算总和
x=x*2  //当前加的数值
n=n+1 //已经加了多少个
print(sum)

continue语句,在循环过程中,可以用break退出当前循环,还可以用continue跳过后续循环代码,继续下一次循环。

sum = 0
x = 0
while True:
    x = x + 1
    if x > 100:
        break
    if x%2==0:   //%表示取余 ‘=’是赋值  ‘==’才是等于
        continue  //当x为偶数的时候 就不执行循环代码
    sum=sum+x
print sum

python之多重循环

for x in ['A', 'B', 'C']:
    for y in ['1', '2', '3']:
        print x + y

x 每循环一次,y 就会循环 3 次,这样,我们可以打印出一个全排列: A1 A2 A3 B1 B2 B3 C1 C2 C3

小练习:

对100以内的两位数,请使用一个两重循环打印出所有十位数数字比个位数数字小的数,例如,23(2 < 3)

for x in [ 1,2,3,4,5,6,7,8,9 ]:
    for y in [1,2,3,4,5,6,7,8,9]:
        if x<y:
            print(str(x)+str(y))

Python中dict的特点

dict的第一个特点是查找速度快,无论dict有10个元素还是10万个元素,查找速度都一样。而list的查找速度随着元素增加而逐渐下降。

不过dict的查找速度快不是没有代价的,dict的缺点是占用内存大,还会浪费很多内容,list正好相反,占用内存小,但是查找速度慢。

由于dict是按 key 查找,所以,在一个dict中,key不能重复。 dict的第二个特点就是存储的key-value序对是没有顺序的!这和list不一样

dict的第三个特点是作为 key 的元素必须不可变,Python的基本类型如字符串、整数、浮点数都是不可变的,都可以作为 key。但是list是可变的,就不能作为 key。 Dict是按照key查找的,key不可以重复。不可拿value查找

dict的作用是建立一组 key 和一组 value 的映射关系,dict的key是不能重复的。 有的时候,我们只想要 dict 的 key,不关心 key 对应的 value,目的就是保证这个集合的元素不会重复,这时,set就派上用场了。 set 持有一系列元素,这一点和 list 很像,但是set的元素没有重复,而且是无序的,这点和 dict 的 key很像

months = set(['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sept','Oct','Nov','Dec'])
x1 = input('请输入您要查询的星期')
x2 = input('请再次输入您要查询的星期')

if x1 in months:
print ('x1: ok')
else:
print ('x1: error')

if x2 in months:
print ('x2: ok')
else:
print ('x2: error')

搞清楚set dict list 与tuple的区别以及语法和各个用途

遍历set

set也是一个集合,so,遍历set和遍历list的方法是一样的,都可以用for循环实现,根据元素的索引位置来输出

s = set([('Adam', 95), ('Lisa', 85), ('Bart', 59)])
for x in s:
print (x[0]+';',x[1])

更新list:

针对下面的set,给定一个list,对list中的每一个元素,如果在set中,就将其删除,如果不在set中,就添加进去。

s = set(['Adam', 'Lisa', 'Paul'])
L = ['Adam', 'Lisa', 'Bllart', 'Paul']
for a in L:
    if a in s:
        s.remove(a)
    else:
        s.add(a)
print s

python的dic中key是唯一的。如果有多个相同的key且对应的value都相同,则只有首个被保存;如果有多个相同key而value不同,则取最后一个value。总之,相同的key只会保存一个。

迭代:

在python中无论是给出一个list或者tuple,我们可以通过for循环来遍历,这种遍历就叫迭代。python的for循环不仅可以用在list或者tuple上,还可以用在任何可以迭代的对象上。 不管有序或者是无序,都可用for循环依次取出集合的每一个元素。

注意: 集合是指包含一组元素的数据结构,现已掌握的包括:

  1. 有序集合:list,tuple,str和unicode;
  2. 无序集合:set
  3. 无序集合并且具有 key-value 对:dict

练习: 请用for循环迭代数列 1-100 并打印出7的倍数。

for i in list(range(1,101)):
print (list(range(1,101))[6::7])
break

输出结果: [7, 14, 21, 28, 35, 42, 49, 56, 63, 70, 77, 84, 91, 98]

标准答案输出是不带中括号的,这里我的输出结果为什么会有中括号呢。因为list(range(1,101))是list类型,在for循环内我是用切片来实现打印出7的倍数,所以print 出的自然是list类型,list类型是用中括号[]括起来的。

以下是更简单的实现方案:

for i in range(1, 101):
if i % 7 == 0:
print (i)

我在学习这个迭代之前学习的是切片功能,所以就用切片方法实现了,哈哈~

索引迭代

想在for循环中拿到元素的索引,用enumerate() 函数

L = ['Adam', 'Lisa', 'Bart', 'Paul']
    for index, name in enumerate(L):
        print index, '-', name 

输出结果: 0 - Adam 1 - Lisa 2 - Bart 3 - Paul 其实 enumerate(L) 是将 ['Adam', 'Lisa', 'Bart', 'Paul’]变成了 [(0,‘Adam'), (1,’Lisa'), (2,’Bart'), (3,’Paul’)]是把集合内的每个元素和它的索引变成了一个touple,

for t in enumerate(L):
    index = t[0]
    name = t[1]
    print index, '-', name

如果我们知道每个tuple元素都包含两个元素,for循环又可以进一步简写为:

for index, name in enumerate(L):
    print index, '-', name

练习: 在迭代 ['Adam', 'Lisa', 'Bart', 'Paul'] 时,如果我们想打印出名次 - 名字(名次从1开始),请考虑如何在迭代中打印出来。 提示:zip函数,可将两个list变为一个list

print(zip([10, 20, 30], ['A', 'B', 'C']))

[(10, 'A'), (20, 'B'), (30, 'C’)]

用zip()函数和range()函数实现:

L = ['Adam', 'Lisa', 'Bart', 'Paul']
order=zip(range(1,5),L)
for a, b in order:
print (a, '-', b)

用enumerate()函数实现:

L = ['Adam', 'Lisa', 'Bart', 'Paul']
for index,name in enumerate(L):
print(index+1,'_',name).  // 由于enumerate()函数是从索引0开始的,所以index要加1

迭代dict的value

for循环可以拿到dict的key 以下方法是迭代dict内对应key的value的值: 针对dict对象有一个values()方法,是将dict转换为一个包含dict内所有value的list

python文档内还有一个itervalues()方法,用该方法替代values()方法,效果是完全一样的

  1. values() 方法实际上把一个 dict 转换成了包含 value 的list。
  2. 但是 itervalues() 方法不会转换,它会在迭代过程中依次从 dict 中取出 value,所以 itervalues() 方法比 values() 方法节省了生成 list 所需的内存。(不过python 3.6中该方法已经被移除了,使用该方法时会报错AttributeError: 'dict' object has no attribute 'Itervalues') 练习: 给定一个dict,d = { 'Adam': 95, 'Lisa': 85, 'Bart': 59, 'Paul': 74 } 请计算所有同学的平均分。
d = { 'Adam': 95, 'Lisa': 85, 'Bart': 59, 'Paul': 74 }
sum = 0.0
for i in d.values():  
sum=sum+i
print (sum/len(d))

同时迭代dict的key和value

使用items方法迭代dict d = { 'Adam': 95, 'Lisa': 85, 'Bart': 59 } Print d.items()

输出结果:dict_items([('Adam', 95), ('Lisa', 85), ('Bart', 59), ('Paul', 74)]) 练习: 请根据dict: d = { 'Adam': 95, 'Lisa': 85, 'Bart': 59, 'Paul': 74 } 打印出 name : score,最后再打印出平均分 average : score。

d = { 'Adam': 95, 'Lisa': 85, 'Bart': 59, 'Paul': 74 }
sum = 0.0
for key, value in d.items():
    sum = sum + v
    print (key,':',value)
print ('average', ':', sum/len(d))

列表生成式

练习:请利用列表生成式生成列表 [1x2, 3x4, 5x6, 7x8, ..., 99x100]

print ([x*(x+1) for x in range(1,100,2)])

输出结果:

函数原型:

range(start, end, scan): 
Range(1,5) //15,不包含5                         1234
Range(1,5,2) //从1开始到5结束不包括5  每隔两个取一个   13
range(5) //表示从05 不包含5                      01234

复杂表达式

在生成的表格中,对于没有及格的同学,请把分数标记为红色。

d = { '大柴': A, 'Chaichai': B, 'Bart': 59 }
def generate_tr(name, score):
return '<tr><td>%s</td><td>%s</td></tr>' % (name, score)
if score<60:
return '<tr><td>%s</td><td style="color:red">%s</td></tr>' % (name, score)
tds = [generate_tr(name, score) for name, score in d.items()]
print ('<table border="1">')
print ('<tr><th>Name</th><th>Score</th><tr>')
print ('\n'.join(tds))
print ('</table>’)

输出结果:

条件过滤:

列表生成式的语句内还可以加入if条件判断 计算1-5内所有数字的平方之和

print([x*x for x in range(1,6)])

如若想要计算1-5之间所有偶数的平方和呢,就可以在列表生成式内加个if条件判断

print([x*x for x in range(1,6) if x%2==0])

练习: 请编写一个函数,它接受一个 list,然后把list中的所有字符串变成大写后返回,非字符串元素将被忽略。

def toUppers(L):
return [x.upper() for x in L if isinstance(x,str)]
print (toUppers(['Hello', 'world', 101]))

多层表达式

一个表达式可以用多个for循环来生成列表

练习: 利用 3 层for循环的列表生成式,找出对称的 3 位数。例如,121 就是对称数,因为从右到左倒过来还是 121。

print ([100*a+10*b+c for a in list(range(1,10)) for b in list(range(1,10)) for c in list(range(1,10)) if a==c])

函数

调用函数:

python内置很多有用的函数,可直接调用。要调用一个函数,需要知道函数的名称和参数。 python内置函数官方链接:http://docs.python.org/2/library/functions.html sum()函数接受一个list作为参数,并返回list所有元素之和。请计算 11 + 22 + 33 + ... + 100100

L = []
x=1
while x <= 100:   //这行代码我初次写的时候是for 不是while ,报了语法错误,for只是判断不是循环
L.append(x*x)
x=x+1
print (sum(L))

编写函数:

定义一个函数需要使用def语句,依次写出函数名/括号/括号中的参数和冒号,然后在缩进块中编写函数体,函数的返回值用return语句返回

请定义一个函数,它接受一个list,返回list中每个元素平方的和

def square_of_sum(L):
sum=0
for a in L:
sum=sum+a*a
return sum
print (square_of_sum([1, 2, 3, 4, 5]))
print (square_of_sum([-5, 0, 5, 15, 25]))

另一种实现方式:

def square_of_sum(L):
       return sum([i * i for i in L])  //函数内调用sum函数
print (square_of_sum([1, 2, 3, 4, 5]))
print (square_of_sum([-5, 0, 5, 15, 25]))

python之定义默认参数

请定义一个 greet() 函数,它包含一个默认参数,如果没有传入,打印 'Hello, world.',如果传入,打印 'Hello, xxx.’

def greet(name=‘world'
print('hello',name)
print(greet())
print(greet('wj’))

python之定义可变参数

定义可变参数的目的也是为了简化调用。假设我们要计算任意个数的平均值,就可以定义一个可变参数:

求平均值:

def average(*args):
sum=0.0   //sum赋值0.0,目的是将sum定义成float类型
if len(args)==0:
return sum
for x in args:
sum=sum+x
return sum/len(args)
print (average())
print (average(1, 2))
print (average(1, 2, 2, 3, 4))

def average(*args):
if len(args)>0:
return sum(args)*1.0/len(args)
else:
return 'hello'

print (average())
print (average(1, 2))
print (average(1, 2, 2, 3, 4))

切片

对list进行切片

取前三个元素: J[0:3] 从索引0开始取,直到索引3为止,但不包括索引3。即取的是索引位置为0/1/2的元素

如果第一个索引是0,还可以省略: J[:3]

只用一个: 表示从头到尾

切片操作可指定第三个参数: J[::2] //表示每两个元素取出来一个 把list换成tuple,切片操作完全相同,只是切片的结果也变成了tuple

练习题: range()函数可以创建一个数列:

range(1, 101)
[1, 2, 3, ..., 100]

请利用切片,取出:

  1. 前10个数;
  2. 3的倍数;
  3. 不大于50的5的倍数。
L = list(range(1, 101))
print (L[0:10])
print (L[2::3])
print (L[4:50:5])

打印出来的结果为:

倒序切片:

可利用切片倒序来取出元素,比如L[-1] 的意思是取L内的最后一个元素

L =list(range(1, 101))
print (L[-10:]) //取最后十个数
print (L[-46::5]) //最后十个5的倍数

对字符串进行切片

对字符串的截取操作仍可用切片来完成,截取出来的仍是字符串。 练习: 字符串有个方法 upper() 可以把字符变成大写字母:

>>> 'abc'.upper()
'ABC'

但它会把所有字母都变成大写。请设计一个函数,它接受一个字符串,然后返回一个仅首字母变成大写的字符串。

def firstCharUpper(s):
firstchar=s[0]
return (firstchar.upper()+s[1:])

print (firstCharUpper('hello'))
print (firstCharUpper('sunday'))
print (firstCharUpper('september'))

以上是我自己的思路,以下是老师给出的更简单的实现方法:

def firstCharUpper(s):
return s[0].upper() + s[1:]   //可利用切片简化字符串操作
print (firstCharUpper('hello'))
print (firstCharUpper('sunday'))
print (firstCharUpper('september’))