初识python

作者 新城 日期 2017-08-20
初识python


一. python变量和数据类型

  1. 整数
    python可以处理任意大小的整数,表示方法和数学中表示方法一样 1,-1,100,-99;
    也可以使用十六进制0x开头 例如0xa表示10 等等
  2. 浮点数
    浮点数就是小数,例如1.2 1.35等等 对于很大的数 可以1.23e9表示1.23的九次方
    整数和浮点数在计算机内部存储的方式是不同的,整数运算永远是精确的,而浮点数运算则可能会有四舍五入的误差。
  3. 字符串
    放置在单引号或者双引号内 ‘leter’ “liter” 同js
  4. 布尔值
    python中布尔值只有True 或者False (注意大小写) 除此之外布尔值可以使用and or not进行计算

    and运算是与运算,只有所有都为 True,and运算结果才是 True
    or运算是或运算,只要其中有一个为 True,or 运算结果就是 True.
    not运算是非运算,它是一个单目运算符,把 True 变成 False,False 变成 True

  5. 空值
    空值是Python里一个特殊的值,用None表示。None不能理解为0,因为0是有意义的,而None是一个特殊的空值。
    此外,Python还提供了列表、字典等多种数据类型,还允许创建自定义数据类型


    print语句

    python 2.7 使用print ‘123’ 输出 ‘123’
    python 3.3 使用print (‘123’) 输出 ‘123’
    – python 变量
    变量名必须是大小写英文、数字和下划线(_)的组合,且不能用数字开头
    1
    2
    a = 1    #a是整数
    t_007 = 'T007' #t-007是字符串

Python中Unicode字符串

在python中想要输出中文的时候在print 中加U
python 2.7 使用print u’’’???’’’ 输出 ‘???’
python 3.3 使用print (u’???’) 输出 ‘???’

python 中布尔值类型运算

与运算:只有两个布尔值都为 True 时,计算结果才为 True。

1
2
3
4
True and True   # ==> True
True and False # ==> False
False and True # ==> False
False and False # ==> False

或运算:只要有一个布尔值为 True,计算结果就是 True。

1
2
3
4
True or True   # ==> True
True or False # ==> True
False or True # ==> True
False or False # ==> False

非运算:把True变为False,或者把False变为True:

1
2
not True   # ==> False
not False # ==> True

Python把0、空字符串’’和None看成 False,其他数值和非空字符串都看成 True,所以:

二. List和Tuple类型

创建List以及对List的增删改

Python内置的一种数据类型是列表:list。list是一种有序的集合,可以随时添加和删除其中的元素。
对应js中数组

1
2
L = ['adam', 95.5, 'lisa', 85, 'bart', 59]
print L

输出结果

1
['adam', 95.5, 'lisa', 85, 'bart', 59]

Python按照索引访问list

1
2
3
4
5
print L[0]
print L[1]
print L[-1]
print L[-2]
adam 95.5 59 bart

(和JS不同超出list长度的话会报错呦!)

为list添加新元素

append()方法添加到list尾部

1
2
3
4
 L = ['Adam', 'Lisa', 'Bart']
L.append('Paul')
print L
['Adam', 'Lisa', 'Bart', 'Paul']

insert()方法添加到list头部

1
2
3
4
 L = ['Adam', 'Lisa', 'Bart']
L.insert(0,'Paul') #第一个参数表示插入的下标号
print L
[ 'Paul','Adam', 'Lisa', 'Bart']

删除list中元素
1
2
3
4
5
6
7
8
L = ['Adam', 'Lisa', 'Paul', 'Bart']
L.pop(2)
L.pop(3)
print L
# Traceback (most recent call last):
File "index.py", line 5, in
L.pop(3)
IndexError: pop index out of range

执行此段代码报错
因为L下表从0开始 当执行pop(2)之后 只剩下三个元素 最大只能执行pop(2) 无法执行pop(3)
有没有感觉和js差不多哇 果然都是解释性语言 语法没辣么严谨 我喜欢

修改list中元素

修改list中指定元素

1
2
3
4
L = ['Adam', 'Lisa', 'Paul', 'Bart']
L[2] = 'Pauls'
print L
['Adam', 'Lisa', 'Pauls', 'Bart']

创建tuple

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

1
t = ('Adam', 'Lisa', 'Bart')  #创建tuple和创建list唯一不同之处是用( )替代了[ ]

创建只有一个元素的tuple

1
2
3
4
5
t = (1)
python 2.7 print t
python 3.3 print (t)
# 报错 因为()既能表示tuple类型也能表示 运算的优先级 所以为了避免引起歧义
python 规定 在一个元素后面添加 ‘,’

  • Python之“可变”的tuple
    前面我们看到了tuple一旦创建就不能修改。现在,我们来看一个“可变”的tuple:
    1
    2
    3
    t = ( 'a' , 'b' , [ 'a' , 'b' ])
    t[2][1] = 'a'
    print (t) #('a', 'b', ['a', 'a'])

没啥说的 就是个嵌套

条件判断和循环

if语句基本使用方法

1
2
3
4
5
6
7
8
9
10
11
12
                  #python 2.7
age = 20
if age >= 18:
print 'your age is', age
print 'adult'
print 'END'
#python 3.3
age = 20
if age >= 18:
print ('your age is', age)
print ('adult')
print ('END')

if-else 基本使用

1
2
3
4
5
score = 55
if score >= 60 : #还是忘记那个冒号 额
print ('passed')
else: #这里也有
print ('failed')

if-elif-else

多级判断

1
2
3
4
5
6
7
8
9
score = 85          #python 2.7
if score >= 90:
print 'excellent'
elif score >= 80:
print 'good'
elif score >= 60:
print 'passed'
else:
print 'failed'

if后面的冒号切记不可以省略 否则报错 注意python有严格的缩进

for循环

1
2
3
4
5
L = [75, 92, 59, 68]    #python 3.3
sum = 0.0
for name in L:
sum += name
print (sum / 4)

while循环

100以内奇数和

1
2
3
4
5
6
sum = 0
x = 1
while x<=100:
sum =sum + x
x=x+2
print (sum)

while循环之break跳出循环;

利用 while True 无限循环配合 break 语句,计算 1 + 2 + 4 + 8 + 16 + … 的前20项的和。

1
2
3
4
5
6
7
8
9
10
sum = 0
x = 1
n = 1
while True:
sum += x
x = pow(2,n) #表示2的n次方
n += 1
if n > 20: #如果n>20退出循环
break
print (sum)

while循环之continue结束本次循环;

1
2
3
4
5
for x in L:
if x < 60: #如果x小于60不执行累加
continue
sum = sum + x
n = n + 1

python 多重循环

1
2
3
for x in ['A', 'B', 'C']:
for y in ['1', '2', '3']:
print (x + y) #A1 A2 A3 B1 B2 B3 C1 C2 C3

Dict和Set类型

什么事Dict

list 和 tuple 可以用来表示顺序集合
Dict就是把对应的key和value关联起来

1
2
3
4
5
6
d = {
'Adam': 95,
'Lisa': 85,
'Bart': 59
}
print (len(d)) # len() 用来计算 d的长度

访问Dict中元素

1
2
3
4
5
6
7
8
9
10
11
12
13
d = {
'Adam': 95,
'Lisa': 85,
'Bart': 59
}
print d['Adam'] # 95
print d['asd'] #访问的元素不存在就会报错
#为避免代码发生错误 有两种方法
#第一种
if 'Paul' in d:
print d['Paul']
#第二种
print d.get('Bart') #使用dict本身提供的一个 get 方法 如果key不存在 就返回none

dict的第一个特点是查找速度快,无论dict有10个元素还是10万个元素,查找速度都一样。而list的查找速度随着元素增加而逐渐下降。
不过dict的查找速度快不是没有代价的,dict的缺点是占用内存大,还会浪费很多内容,list正好相反,占用内存小,但是查找速度慢。
由于dict是按 key 查找,所以,在一个dict中,key不能重复。

dict 中添加新的key:value

1
2
3
4
5
6
d = {
'Adam': 95,
'Lisa': 85,
'Bart': 59
}
d['Paul'] = 72

dict 遍历

1
2
3
4
5
6
7
8
9
d = {
'Adam': 95,
'Lisa': 85,
'Bart': 59
}
for key in d:
print str(key)+":"+str(d[key])
for k,v in d.items(): #待学习
print k,':',v

python 中set

dict的作用是建立一组 key 和一组 value 的映射关系,dict的key是不能重复的。

创建 set 的方式是调用 set() 并传入一个 list,list的元素将作为set的元素:

1
2
s = set(['A', 'B', 'C'])
print (s)

请注意,上述打印的形式类似 list, 但它不是 list,仔细看还可以发现,打印的顺序和原始 list 的顺序有可能是不同的,因为set内部存储的元素是无序的。

set不能包含相同的元素 当我们传入相同的元素时set会自动过滤掉

python 访问 set

由于set不能识别小写的名字,请改进set,使得 ‘adam’ 和 ‘bart’都能返回True。

1
2
3
4
5
a = set(['Adam', 'Lisa', 'Bart', 'Paul'])
b = set(['adam','bart'])
s =a|b
print 'adam' in s
print 'bart' in s

Python之 set的特点

  • set的内部结构和dict很像,唯一区别是不存储value,因此,判断一个元素是否在set中速度很快。
    • set存储的元素和dict的key类似,必须是不变对象,因此,任何可变对象是不能放入set中的。
  • set存储的元素是没有顺序的。
    月份也可以用set表示,请设计一个set并判断用户输入的月份是否有效

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    months = set(['Feb','Sun'])
    x1 = 'Feb'
    x2 = 'Suns'
    if x1 in months:
    print 'x1: ok'
    else:
    print 'x1: error'
    if x2 in months:
    print 'x2: ok'
    else:
    print 'x2: error'

    Python之 遍历set

    1
    2
    3
    4
    5
    s = set([('Adam', 95), ('Lisa', 85), ('Bart', 59)])
    for name,score in s:
    print name,':',score #Lisa : 85
    #Adam : 95
    #Bart : 59

更新set

由于set存储的是一组不重复的无序元素,因此,更新set主要做两件事:

一是把新的元素添加到set中,二是把已有元素从set中删除。

  1. 添加元素时 使用set add()方法

    1
    2
    3
    s = set([1, 2, 3])
    s.add(4) #如果添加的元素已经存在于set中,add()不会报错,但是不会加进去了:
    print s #set([1, 2, 3, 4])
  2. 删除set中的元素时,用set的remove()方法:
    如果删除的元素不存在set中,remove()会报错
    用add()可以直接添加,而remove()前需要判断。

    1
    2
    3
    s = set([1, 2, 3, 4])
    s.remove(4) #如果删除的元素不存在set中,remove()会报错:
    print s #set([1, 2, 3])

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

1
2
3
4
5
6
7
8
s = set(['Adam', 'Lisa', 'Paul'])
L = ['Adam', 'Lisa', 'Bart', 'Paul']
for name in L:
if name in s: #如果L中元素在set中 将其添加进去
s.remove(name)
else:
s.add(name)
print s

函数

Python内置了很多有用的函数,我们可以直接调用
要调用一个函数,需要知道函数的名称和参数,比如求绝对值的函数 abs,它接收一个参数。
传送门官方文档

1
2
3
4
5
6
7
8
#比较函数
cmp(1, 2) -1 #前者和后者比较
cmp(3, 2) 1
cmp(1, 2) 0
#转换为整数
int('123') #123
#转换为字符串
str(123) #123

sum()函数接受一个list作为参数,并返回list所有元素之和。请计算 11 + 22 + 33 + … + 100100。

1
2
3
4
5
6
7
8
9
10
L = xrange(1, 101)
print sum([i*i for i in L])
#--------
L = []
x = 1
N = 100
while x <= N:
L.append(x*x)
x=x+1
print sum(L) #将List整体传入到 sum中 进行累加

  • 自定义函数

    在Python中,定义一个函数要使用 def 语句,依次写出函数名、括号、括号中的参数和冒号:,然后,在缩进块中编写函数体,函数的返回值用 return 语句返回。
    1
    2
    3
    4
    5
    6
    7
    def square_of_sum(L):       #自定义函数返回平方和
    a = 0
    for name in L:
    a += name*name
    return a
    print square_of_sum([1, 2, 3, 4, 5])
    print square_of_sum([-5, 0, 5, 15, 25])

Python函数之返回多值

一元二次方程的定义是:ax² + bx + c = 0
请编写一个函数,返回一元二次方程的两个解。

1
2
3
4
5
6
7
8
9
10
import math
def quadratic_equation(a, b, c):
if (b*b-4*a*c)<0:
return "no real root"
else:
x=b*b-4*a*c
return (-b+math.sqrt(x))/(2*a),(-b-math.sqrt(x))/(2*a)

print quadratic_equation(2, 3, 0)
print quadratic_equation(1, -6, 5)

执行结果




递归函数
在函数内部,可以调用其他函数。如果一个函数在内部调用自身本身,这个函数就是递归函数。
比如说n的阶乘 12345···(n-1)n

>fact(n) = n! = 1 2 3 (n-1) n = (n-1)! n = fact(n-1) * n

以下是执行结果


递归函数的优点是定义简单,逻辑清晰。理论上,所有的递归函数都可以写成循环的方式,但循环的逻辑不如递归清晰。

使用递归函数需要注意防止栈溢出。在计算机中,函数调用是通过栈(stack)这种数据结构实现的,
每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,
所以,递归调用的次数过多,会导致栈溢出。可以试试计算 fact(10000)

汉诺塔 (http://baike.baidu.com/view/191666.htm) 的移动也可以看做是递归函数。
我们对柱子编号为a, b, c,将所有圆盘从a移到c可以描述为:
如果a只有一个圆盘,可以直接移动到c;
如果a有N个圆盘,可以看成a有1个圆盘(底盘) + (N-1)个圆盘,首先需要把 (N-1) 个圆盘移动到 b,然后,将 a的最后一个圆盘移动到c,再将b的(N-1)个圆盘移动到c。
请编写一个函数,给定输入 n, a, b, c,打印出移动的步骤:
move(n, a, b, c)
例如,输入 move(2, ‘A’, ‘B’, ‘C’),打印出:
A –> B
A –> C
B –> C

1
2
3
4
5
6
7
8
9
#-*- coding:utf-8 -*-
def move(n, x, y, z):
if n==1:
print (x,'-->',z)
return
move(n-1,x,z,y)#将前n-1个盘子从x移动到y上
move(1,x,y,z)#将最底下的最后一个盘子从x移动到z上
move(n-1,y,x,z)#将y上的n-1个盘子移动到z上
move(4, 'A', 'B', 'C')

Python之定义默认参数

定义函数的时候可以有默认参数。例如Python自带的 int() 函数,其实就有两个参数,我们既可以传一个参数,又可以传两个参数:

1
2
3
int('123')   #123  默认十进制

int('123', 8) # 83 转换为8进制

定义greet()函数 当初如参数为空是输出 ‘hello world’ 当传入参数为其它时 输出 ‘hello 其他’

1
2
3
4
def greet (s = 'world'):
print ('hello,' + s)
greet()
greet('boys')

python 可变参数

如果想让一个函数能接受任意个参数,我们就可以定义一个可变参数:
下面定义了一个函数 接受多个参数 求平均值

1
2
3
4
5
6
7
8
9
10
11
12
def average(*args):
sum = 0 #在函数内部,直接把变量 args 看成一个 tuple 就好了。 (1,2,3,4,5)
i = len(args)
for sc in args:
sum += sc
if i==0:
return 0.0
else:
return float(sum)/i
print average()
print average(1, 2)
print average(1, 2, 2, 3, 4)

切片

就是对list的部分元素截取
>L = [‘Adam’,’Lisa’,’Bart’,’Paul’]
取前三个元素,首先想到的笨办法是:[L[0],L[1],L[2]]
然后我们扩展开一下 可以利用循环

1
2
3
4
r = []
n = 3
for i in range(n):
r.append(L[i])

对这种经常取指定索引范围的操作,用循环十分繁琐,因此,Python提供了切片(Slice)操作符

1
2
3
4
5
6
7
8
9
10
L = ['Adam', 'Lisa', 'Bart', 'Paul']        #list

L[0:3] #截取的时候 含头不含尾 也可以写为 L[:3] 输出 ['Adam', 'Lisa', 'Bart']

L[1:3] #索引从1 开始取出两个元素 输出 ['Lisa', 'Bart']

L[:] #L[:]实际上复制出了一个新list
#表示从头到尾 输出 ['Adam', 'Lisa', 'Bart', 'Paul']

L[::2] # L[0::2] 从0开始取到结尾 每隔两个取一次

请利用切片,取出:1. 前10个数;2. 3的倍数;3. 不大于50的5的倍数。

1
2
3
4
L = range(1, 101)       #生成[1,2,3,4,...101] 创建一个数列
print L[:10] #截取从0到10 L[0]-L[9]
print L[2::3] #截取从L[2]开始到结尾 没隔三个数字截取一位
print L[4:50:5] #从L[4]开始截取 到L[50]结束 每隔五位数截取一位

倒序切片

list支持 L[-1]倒数取元素
同样list也支持倒数取切片

1
2
3
4
5
6
7
8
9
L = ['Adam', 'Lisa', 'Bart', 'Paul']

L[-2:] #输出['Bart', 'Paul'] 倒数第二位截取到最后

L[:-2] #输出['Adam', 'Lisa'] 开头截取到倒数第二位

L[-3:-1] #['Lisa', 'Bart'] 截取倒数第三位到倒数第二位 注意不包含倒数第一位

L[-4:-1:2] #['Adam', 'Bart'] 倒数第四位截取到倒数第二位 每隔两位截取一个

相比js感觉方便很多

对字符串进行切片

字符串 ‘xxx’和 Unicode字符串 u’xxx’也可以看成是一种list 字符串也可以用切片操作,只是操作结果仍是字符串:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
'ABCDEFG'[:3]    #输出  'ABC'

def StrUpper(s,n=1):
return s[:n].upper()+s[n:]

print StrUpper('hello')
print StrUpper('sunday')
print StrUpper('september')

#--------------------------
import string #导入string调用方法

def firstCharUpper(s):
return string.capitalize(s)

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

迭代

在Python中,如果给定一个list或tuple,我们可以通过for循环来遍历这个list或tuple,这种遍历我们成为迭代(Iteration)

Python 的 for循环不仅可以用在list或tuple上,还可以作用在其他任何可迭代对象上

注意: 集合是指包含一组元素的数据结构,我们已经介绍的包括:

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

下面这话表示不是很懂

迭代与按下标访问数组最大的不同是,后者是一种具体的迭代实现方式,而前者只关心迭代结果,根本不关心迭代内部是如何实现的。

索引迭代

Python中,迭代永远是取出元素本身,而非元素的索引。

对于有序集合,元素确实是有索引的。有的时候,我们确实想在 for 循环中拿到索引,怎么办?




1
2
3
4
5
6
7
L = ['Adam', 'Lisa', 'Bart']
s = range(1,len(L)) #生成(1,2,3)
a = zip(s,L) #将两个list合并成一个[(1, 'Adam'), (2, 'Lisa'), (3, 'Bart')]
for index, name in a:
print index, '-', name #1 - Adam
2 - Lisa
3 - Bart


#### 迭代dict的value
python(dict) === javascript(json)
value()函数就是将dict中value 单独提取出来放到一个list中


itervalues() 方法不会转换,它会在迭代过程中依次从 dict 中取出 value,所以 itervalues() 方法比 values() 方法节省了生成 list 所需的内存

1
2
3
4
5
6
7
d = { 'Adam': 95, 'Lisa': 85, 'Bart': 59 }
print d.itervalues()
# <dictionary-valueiterator object at 0x106adbb50>
for v in d.itervalues():
print v
# 85
# 95

迭代dict 的 key和value

tems() 方法把dict对象转换成了包含tuple的list,我们对这个list进行迭代,可以同时获得key和value




### 列表生成式
- 生成相对比较简单的list
1
2
3
4
5
6
7
range(1, 11)    #生成[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
L = []
for x in range(1, 11): #将1-10 遍历 操作每个value
L.append(x * x) #生成[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

#简写
[x * x for x in range(1, 11)] #生成[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]


- 复杂表达式
可以生成table表格
1
2
3
4
5
6
7
8
9
10
11
12
13
#  '#'表示格式化字符串   %s  %s       %(name,scors)   第一个s%  表示name      第二个s%  表示 scors
####return '<tr><td>%s</td><td style="color:red">%s</td></tr>' % (name, score)
d = { 'Adam': 95, 'Lisa': 85, 'Bart': 59 } #所有童鞋分数json
def generate_tr(name, score): #定义函数
if score < 60:
return '<tr><td>%s</td><td style="color:red">%s</td></tr>' % (name, score) #小于60分标红
return '<tr><td>%s</td><td>%s</td></tr>' % (name, score) #否则正常输出

tds = [generate_tr(name, score) for name, score in d.items()] #for循环的时候 每次将name score 都调用一次函数
print ('<table border="1">')
print ('<tr><th>Name</th><th>Score</th><tr>')
print ('\n'.join(tds)) #拼接字符串
print ('</table>')




  • 条件过滤

    1
    2
    3
    [x * x for x in range(1, 11)]     # [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
    #下面过滤出来只有偶数的平方
    [x * x for x in range(1, 11) if x % 2 == 0] #[4, 16, 36, 64, 100]



  • 多层表达式
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    L=[]
    for x in range(1,10):
    for y in range(10):
    for z in range(1,10):
    if x==z :
    L.append(100*x+10*y+z)
    print L

    print [100 * x + 10 * y + z for x in range(1, 10) for y in range(10) for z in range(10) if x==z]

    print [x for x in range(100,1000) if str(x)[0]==str(x)[-1]]