廖雪峰
慕课Python3入门教程

在Python2使用除法可能和Python3得到不一样的结果

# python2
num1 = 10
num2 = 3
result = num1 / num2
print(result) # ==> 3
# python3
num1 = 10
num2 = 3
result = num1 / num2
print(result) # ==> 3.3333333333333335

可以看到在python2,得到的是一个整数的结果,这是因为除数和被除数都是整数时,得到的结果也默认保存为整数了,这是非常不科学的,因此在python3,改进了这一点。

地板除

忽略小数部分

10//4 # ==> 2
10//2.5 # ==> 4.0 转换为浮点数
10//3 # ==> 3

小数点位数

num = 10 / 3
round(num, 2) # ==> 3.33 默认四舍五入

布尔运算

python中把0、空字符串和None看成False,其他数值和非空字符都看成True

a = True
print(a and 0 or 99) # ==> 99

字符串

# raw字符串,不需要转义
# 不能表示多行,不能包含'或"
r'\(~_~)/ \(~_~)/'
# 多行字符串
'''Line 1
Line 2
Line 3'''
# raw多行字符串
r'''Python is created by "Guido".
It is free and easy to learn.
Let's start learn Python in imooc!'''

字符串模板

通过string.format使用模板字符串

# 字符串模板
template = 'Hello {}'
# 模板数据内容
world = 'World'
result = template.format(world)
print(result) # ==> Hello World

# 指定顺序
template = 'Hello {0}, Hello {1}, Hello {2}, Hello {3}.'
result = template.format('World', 'China', 'Beijing', 'imooc')
print(result) # ==> Hello World, Hello China, Hello Beijing, Hello imooc.
# 调整顺序
template = 'Hello {3}, Hello {2}, Hello {1}, Hello {0}.'
result = template.format('World', 'China', 'Beijing', 'imooc')
print(result) # ==> Hello imooc, Hello Beijing, Hello China, Hello World.

# 指定{}的名字w,c,b,i
template = 'Hello {w}, Hello {c}, Hello {b}, Hello {i}.'
world = 'World'
china = 'China'
beijing = 'Beijing'
imooc = 'imooc'
# 指定名字对应的模板数据内容
result = template.format(w = world, c = china, b = beijing, i = imooc)
print(result) # ==> Hello World, Hello China, Hello Beijing, Hello imooc.

字符串切片

使用[]填入两个数字,用冒号:分开,表示开始位置和结束位置,半闭半开/包前不包后

ab = s[0:2] # 取字符串s中的第一个字符到第三个字符,不包括第三个字符
print(ab) # ==> AB

elif

elif = else-if,如果某个判断为True,执行完对应的代码块,后面的条件判断就直接忽略,不再执行。

score = 95
if score < 60:
    print('抱歉,考试不及格')
elif score >= 80:
    print('恭喜你,拿到优秀的成绩')
elif score >= 90:
    print('恭喜你,拿到卓越的成绩')
else:
    print('恭喜你,考试及格')
# 只输出'恭喜你,拿到优秀的成绩'

for循环

循环任意序列的项目,如列表或字符串

for letter in 'Python':     # 第一个实例
   print '当前字母 :', letter
 
fruits = ['banana', 'apple',  'mango']
for fruit in fruits:        # 第二个实例
   print '当前水果 :', fruit

# 通过序列索引迭代
fruits = ['banana', 'apple',  'mango']
for index in range(len(fruits)):
   print '当前水果 :', fruits[index]

# 循环使用else语句
# else会在语句正常执行完(即不通过break跳出)后执行,while...else同理
for num in range(10,20):  # 迭代 10 到 20 之间的数字
   for i in range(2,num): # 根据因子迭代
      if num%i == 0:      # 确定第一个因子
         j=num/i          # 计算第二个因子
         print '%d 等于 %d * %d' % (num,i,j)
         break            # 跳出当前循环
   else:                  # 循环的 else 部分
      print num, '是一个质数'

list

越界切片不会报错但不会获得任何元素

list = ['a', 'b', 'c']
list = list[5:10]
print(list) # ==> []

倒序访问

names = ['Alice', 'Bob', 'David', 'Ellena']
print(names[-1]) # ==> Ellena
print(names[-2]) # ==> David
print(names[-3]) # ==> Bob
print(names[-5]) # ==> 越界

添加元素

list.append(item)list.insert(index, item)

# 加入队尾
names = ['Alice', 'Bob', 'David', 'Ellena']
names.append('Candy')
print(names) # ==> ['Alice', 'Bob', 'David', 'Ellena', 'Candy']

# 插入队中
names = ['Alice', 'Bob', 'David', 'Ellena']
names.insert(2, 'Candy')
print(names) # ==> ['Alice', 'Bob', 'Candy', 'David', 'Ellena']

删除元素

list.pop(?index)

# 删除队尾
L = ['Alice', 'Bob', 'Candy', 'David', 'Ellena']
name = L.pop()
print(name) # ==> Ellena
print(L) # ==> L = ['Alice', 'Bob', 'Candy', 'David']

# 删除队中
L = ['Alice', 'Bob', 'Candy', 'David', 'Ellena']
name = L.pop(2)
print(name) # ==> Candy
print(L) # ==> ['Alice', 'Bob', 'David', 'Ellena']

tuple(元组)

使用小括号()定义

tuple中的元素不可改变(引用不变),并且也不能向tuple中添加或者删除元素(对于组合类型的tuple则不受约束。如(1, 'CH', [3, 4])

T = ('Alice', 'Bob', 'Candy', 'David', 'Ellena')
# 通过下标的方式访问元素
print(T[0]) # ==> Alice
print(T[4]) # ==> Ellena
# 切片
print(T[1:3]) # ==> ('Bob', 'Candy')

可以用tuple(<L>)将列表转化为元组,反过来也可以用list(<T>)将元组转化为列表

由于tuple不变,所以有一些便捷的方法去访问tuple

# count()统计元素出现的次数
T = (1, 1, 2, 2, 3, 3, 1, 3, 5, 7, 9)
print(T.count(1)) # ==> 3
print(T.count(5)) # ==> 1
print(T.count(10)) # ==> 0 对不存在的元素不报错而是返回0

# index()返回元素的下标
T = (1, 1, 2, 2, 3, 3, 1, 3, 5, 7, 9)
T.index(9) # ==> 10
T.index(5) # ==> 8
T.index(1) # ==> 0 # 多次出现,返回第一次出现的位置
T.index(100) # 报错:ValueError 与count()不同,如果元素不存在则报错

表示tuple用的()与运算符的冲突

由于表示tuple使用的是小括号(),但是改变运算优先级使用的也是小括号(),所以在某些场景下可能会发生输入与输出不一致的情况。

T = (1)
print(T) # ==> 1 与下面的表示冲突,并且改变优先级的小括号优先级更高

result = 3 * 4 - 2
print(result) # ==> 10
# 改变优先级,先运算减法
result = 3 * (4 - 2)
print(result) # ==> 6

所以,创建单元素tuple时使用以下格式

T = (1, )
print(T) # ==> (1, )

而对于多元素tuple,加不加最后的逗号都是一样的

dict 字典

与json比较相似。

必须使用不可变的元素作为key。如基本类型(数字、字符串)和元组。

d = {
    'Alice': 45,
    'Bob': 60,
    'Candy': 75,
    'David': 86,
    'Ellena': 49
}

# 读取: dict[<key>]
print(d['Alice']) # ==> 45
print(d['Do']) # ==> 报错KeyError: 使用中括号访问不存在的key会报错

# 读取:dict.get(<key>)
print(d.get('Alice')) # ==> 45
print(d.get('Do')) # ==> None 使用get访问不存在的key则不报错,返回None

# 写入:dict[<key>] = <value>
d['Chen'] = 110 # ==> 可以是任意类型
d['Alice'] = 100 # ==> 更新Alice的值

# 删除:dict.pop(<key>)
d.pop('Alice') # ==> success
d.pop('Alice') # ==> 报错:KeyError 不存在则报错

# 遍历
for key, value in d.items():
    if value > 60:
        print(key, value)
# ==> Candy 75
# ==> David 86

set 不重复元素

大部分操作与list相同。但是:

  1. set内部是无序的(不能使用下标访问set)
  2. set不包含重复的元素

使用set(<L>)将list或tuple转化为set

与Java的HashSet类似。


# 没有直接创建set的方法
names = ['Alice', 'Bob', 'Candy', 'David', 'Ellena']
name_set = set(names)

'Alice' in name_set # ==> True
'Bobby' in name_set # ==>False
'bob' in name_set # ==> False 大小写敏感

# 添加set.add(<I>)

# 批量添加
new_names = ['Hally', 'Isen', 'Jenny', 'Karl']
name_set.update(new_names)

# 删除
name_set.remove('Bob') # ==> success
name_set.remove('Bob') # ==> 报错:KeyError 不存在则报错

# 不报错删除
name_set.discard('Bob') # ==> success
name_set.discard('Bob') # ==> success

# 子集和超集
s1 = set([1, 2, 3, 4, 5])
s2 = set([1, 2, 3, 4, 5, 6, 7, 8, 9])
# 判断s1是否为s2的子集
s1.issubset(s2) # ==> True
# 判断s2是否为s1的超集
s2.issuperset(s1) # ==> True

# 重合
s1 = set([1, 2, 3, 4, 5])
s2 = set([1, 2, 3, 4, 5, 6, 7, 8, 9])
s1.isdisjoint(s2) # ==> False,因为有重复元素1、2、3、4、5

函数

# 定义函数
def list_sum(L):
    result = 0
    for num in L:
        result = result + num
    return result

# 多返回值
def data_of_square(side):
    C = 4 * side
    S = side * side
    return C, S
C1, S1 = data_of_square(16) # 返回为tuple
print('周长 = {}'.format(C1)) # ==> 周长 = 64
print('面积 = {}'.format(S1)) # ==> 面积 = 256
# 或用tuple下标获取
C2 = result[0]
S2 = result[1]
print('周长 = {}'.format(C2)) # ==> 周长 = 64
print('面积 = {}'.format(S2)) # ==> 面积 = 256

# 参数类型限制isinstance(<I>, <type>)
def my_abs(x):
    if not isinstance(x, int) or not isinstance(x, float):
        print('param type error.')
        return None
    if x >= 0:
        return x
    else:
        return -x

# 默认参数
# 由于函数的参数按从左到右的顺序匹配,所以默认参数只能定义在必需参数的后面,否则将会出现错误。
# 注意:默认参数指向不变的对象(引用不变),如果指向数组并对其进行操作的话可能产生意想不到的情况
def power(x, n=2):
    s = 1
    while n > 0:
        n = n - 1
        s = s * x
    return s
    
# 可变参数(传入时为tuple,并且长度可能为0)
def average(*args):
    sum = 0
    for item in args:
        sum += item
    avg = sum / len(args)
    return avg
    
# 可变关键字参数
def func(param1, param2, param3 = None, *args, **kwargs):
    print(param1)
    print(param2)
    print(param3)
    print(args)
    print(kwargs)

func(100, 200, 300, 400, 500, name = 'Alice', score = 100)
# ==> 100
# ==> 200
# ==> 300
# ==> (400, 500)
# ==> {'name': 'Alice', 'score': 100}

注意:在使用可变参数的时候不要把可变参数放在不变参数前面。因为这样虽然写的时候不报错,但是运行时会造成后面的不变参数无法读取到而报错