Python语法基础

1.基本使用

1.1 数据类型

  • 常用数据类型 Common Data Types
类型 例子
整数 -100
浮点数 3.1416
字符串 'hello'
列表 [1, 1.2, 'hello']
字典 {'dogs': 5, 'pigs': 3}
Numpy数组 array([1, 2, 3])
  • 其他类型 Others
类型 例子
长整型 1000000000000L
布尔型 True, False
元组 ('ring', 1000)
集合 {1, 2, 3}
Pandas类型 DataFrame, Series
自定义 Object Oriented Classes

1.2 基础数学运算

  • 基本的加减乘除
    python可以直接运算数字,也可以加 print 进行运算.
>>> 1+1
2
>>> 2-1
1
>>> 2*3
6
>>> 4/3
1.3333333333333333
  • 幂运算
    区别于Matlab,在python中,幂运算用两个**表示,如3的平方为3**2 , **3表示立方,**4表示4次方,依次类推。
>>> 3**2   # **2 表示2次方
"""
9
"""
>>> 3**3   # **3 表示3次方
"""
27
"""
>>> 3**4
"""
81
"""
  • 取余 % 和 取商 //
    余数符号为“%”,见代码。
>>> 9%3
"""
0
"""
>>> 9//3
"""
3
"""
  • 运算优先级
    1. ( ) 括号
    2. ** 幂指数运算
    3. * / // % 乘,除,整数除法,取余运算
    4. '+ -' 加减
  • 复数 Complex Numbers
    Python 使用 j 来表示复数的虚部:
>>> a = 1 + 2j
>>> type(a)
"""<class 'complex'>"""

  可以查看它的实部,虚部以及共轭:

>>> a.real
1.0
>>> a.imag
2.0
>>> a.conjugate()
(1-2j)
  • 简单数学函数

1.绝对值

>>> abs(-12.4)
12.4

2.取整

>>> round(21.6)
22

3.最大最小值

>>> min(2, 3, 4, 5)
2
>>> max(2, 4, 3)
4
  • 其他表示

1.科学计数法

>>> 1e-6
1e-06

2. 16进制:前面加0x修饰,后面使用数字0-9A-F

>>> 0xFF
255

3. 8进制:前面加0o修饰,后面使用数字0-7

>>> 0o67
55

4. 2进制:前面加0b修饰,后面使用数字0或1:

>>> 0b101010
42

5. 原地计算

>>> b = 2.5
>>> b += 2
>>> b *= 2
>>> b /= 2
>>> b
4.5

5. 链式比较
常用的比较符号包括:<, >, <=, >=, ==, !=

>>> x = 2 
>>> 1 < x <= 3
True

1.3 字符串 String

  • 生成字符串
    Python中可以使用一对单引号''或者双引号""生成字符串。
>>> s = "hello, world"
>>> s = 'hello world'
  • 简单操作

1. 加法

>>> s = 'hello ' + 'world'
>>> s
'hello world'

2.字符串与数字相乘

>>> "echo" * 3
'echoechoecho'

3.字符串长度

>>> len(s)
11
  • 字符串方法
    Python是一种面向对象的语言,面向对象的语言中一个必不可少的元素就是方法,而字符串是对象的一种,所以有很多可用的方法。跟很多语言一样,Python使用以下形式来调用方法:对象.方法(参数)

1.分割
s.split()s按照空格(包括多个空格,制表符\t,换行符\n等)分割,并返回所有分割得到的字符串。

>>> numbers = line.split()
>>> numbers
['1', '2', '3', '4', '5']

  s.split(sep)以给定的sep为分隔符对s进行分割。

>>> line = "1,2,3,4,5"
>>> numbers = line.split(',')
>>> numbers
['1', '2', '3', '4', '5']

2.连接
  与分割相反,s.join(str_sequence)的作用是以s为连接符将字符串序列str_sequence中的元素连接起来,并返回连接后得到的新字符串。

>>> s = ' '
>>> s.join(numbers)
'1 2 3 4 5'
>>> s = ','
>>> s.join(numbers)
'1,2,3,4,5'

3.替换
s.replace(part1, part2)将字符串s中指定的部分part1替换成想要的部分part2,并返回新的字符串。

>>> s = "hello world"
>>> s.replace('world', 'python')
'hello python'

  此时,s的值并没有变化,替换方法只是生成了一个新的字符串。

>>> s
'hello world'

4.大小写转换
s.upper()方法返回一个将s中的字母全部大写的新字符串。
s.lower()方法返回一个将s中的字母全部小写的新字符串。

>>> "hello world".upper()
'HELLO WORLD'

  这两种方法也不会改变原来s的值:

>>> s = "HELLO WORLD"
>>> s.lower()
'hello world'
>>> s
'HELLO WORLD'

5.去除多余空格
s.strip()返回一个将s两端的多余空格除去的新字符串。
s.lstrip()返回一个将s开头的多余空格除去的新字符串。
s.rstrip()返回一个将s结尾的多余空格除去的新字符串。

>>> s = "  hello world   "
>>> s.strip()
'hello world'

  s的值依然不会变化:

>>> s
'  hello world   '
>>> s.lstrip()
'hello world   '
>>> s.rstrip()
'  hello world'

6.更多方法
  可以使用dir函数查看所有可以使用的方法

>>> dir(s)
['__add__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__gt__', '__hash__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'capitalize', 'casefold', 'center', 'count', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'format_map', 'index', 'isalnum', 'isalpha', 'isdecimal', 'isdigit', 'isidentifier', 'islower', 'isnumeric', 'isprintable', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'maketrans', 'partition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill']
  • 多行字符串
    Python 用一对 """ 或者 ''' 来生成多行字符串:
>>> a = """hello world.
... it is a nice day."""
>>> print(a)
hello world.
it is a nice day.

  在储存时,我们在两行字符间加上一个换行符 '\n'

>>> a
'hello world.\nit is a nice day.'
  • 使用 () 或者 \ 来换行
    当代码太长或者为了美观起见时,我们可以使用两种方法来将一行代码转为多行代码:() 或者 \
>>> a = ("hello, world. "
...     "it's a nice day. "
...     "my name is xxx")
>>> a
"hello, world. it's a nice day. my name is xxx"
>>> a = "hello, world. " \
...     "it's a nice day. " \
...     "my name is xxx"
>>> a
"hello, world. it's a nice day. my name is xxx"
  • 强制转换为字符串
    str(ob)强制将ob转化成字符串。
    repr(ob)也是强制将ob转化成字符串。
>>> str(1.1 + 2.2)
'3.3000000000000003'
>>> repr(1.1 + 2.2)
'3.3000000000000003'
  • 整数与不同进制的字符串的转化
    可以将整数按照不同进制转化为不同类型的字符串。
    十六进制:
>>> hex(255)
'0xff'

  八进制:

>>> oct(255)
'0o377'

  二进制:

>>> bin(255)
'0b11111111'

  可以使用 int 将字符串转为整数:

>>> int('23')
23

  还可以指定按照多少进制来进行转换,最后返回十进制表达的整数:

>>> int('FF',16)
255
>>> int('377',8)
255
>>> int('11111111',2)
255

float 可以将字符串转换为浮点数:

>>> float('3.5')
3.5
  • 格式化字符串
    Python用字符串的format()方法来格式化字符串。具体用法如下,字符串中花括号 {} 的部分会被format传入的参数替代,传入的值可以是字符串,也可以是数字或者别的对象。
>>> '{} {} {}'.format('a', 'b', 'c')
'a b c'

  可以用数字指定传入参数的相对位置:

>>> '{2} {1} {0}'.format('a', 'b', 'c')
'c b a'

  还可以指定传入参数的名称:

>>> '{color} {n} {x}'.format(n=10, x=1.5, color='blue')
'blue 10 1.5'

  可以在一起混用:

>>> '{color} {0} {x} {1}'.format(10, 'foo', x = 1.5, color='blue')
'blue 10 1.5 foo'

  可以用{<field name>:<format>}指定格式:

>>> from math import pi
>>> '{0:10} {1:10d} {2:10.2f}'.format('foo', 5, 2 * pi)
'foo                 5       6.28'

  也可以使用旧式的 % 方法进行格式化,具体规则与C中相同。

>>> s = "some numbers:"
>>> x = 1.34
>>> y = 2
>>> # 用百分号隔开,括号括起来
... t = "%s %f, %d" % (s, x, y)
>>> t
'some numbers: 1.340000, 2'

1.4 自变量 Variable

  • 自变量命名规则
    可以将一个数值,或者字符串串附值给自变量,如 apple=1 中,apple 为自变量的名称,1 为自变量的值。 也可以将字符串赋值给自变量 apple='iphone7 plus'
>>> apple=1       #赋值 数字
>>> print(apple)
"""
1
"""

>>> apple='iphone 7 plus'   #赋值 字符串
>>> print(apple)
"""
iphone 7 plus
"""

  一次定义多个自变量 a,b,c=1,2,3

>>> a,b,c=11,12,13
>>> print(a,b,c)
"""
11 12 13
"""

2.元组,列表,字典

2.1 元组,列表

  • 元组 Tuple
    元组Tuple是个有序序列,但是元组是不可变的,用小括号、或者无括号来表述,是一连串有顺序的数字。
>>> a_tuple = (12, 3, 5, 15 , 6)
>>> another_tuple = 12, 3, 5, 15 , 6

  可以索引,切片:

>>> t = (10, 11, 12, 13, 14)
>>> t[0]
10
>>> t[1:3]
(11, 12)

  但是元组是不可变的:

>>> # 会报错
... t[0] = 1
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
TypeError: 'tuple' object does not support item assignment

单个元素的元组生成:由于 ()在表达式中被应用,只含有单个元素的元组容易和表达式混淆,所以采用下列方式定义只有一个元素的元组:

>>> a = (10,)
>>> a
(10,)
>>> type(a)
"""<class 'tuple'>"""

>>> a = (10)
>>> type(a)
"""<class 'int'>"""

  将列表转换为元组:

>>> a = [10, 11, 12, 13, 14]
>>> tuple(a)
(10, 11, 12, 13, 14)
  • 元组方法
    由于元组是不可变的,所以只能有一些不可变的方法,例如计算元素个数 count 和元素位置 index ,用法与列表一样。
>>> a = [10, 11, 12, 13, 14]
>>> a.count(10)
1
>>> a.index(12)
2
  • 为什么需要元组
    1. 旧式字符串格式化中参数要用元组;
    2. 在字典中当作键值;
    3. 数据库的返回值……
  • 列表 List
    在Python中,列表是一个有序的序列。列表用一对 [] 生成,中间的元素用 , 隔开,其中的元素不需要是同一类型,同时列表的长度也不固定。
>>> l = [1, 2.0, 'hello']
>>> print(l)
[1, 2.0, 'hello']

  空列表可以用 [] 或者 list() 生成:

>>> empty_list = []
>>> empty_list
[]
>>> empty_list = list()
>>> empty_list
[]
  • 两者对比
    他们的元素可以一个一个地被迭代、输出、运用、定位取值:
for content in a_list:
    print(content)
"""
12
3
67
7
82
"""

for content_tuple in a_tuple:
    print(content_tuple)
"""
12
3
5
15
6
"""

下一个例子,依次输出a_tuplea_list中的各个元素:

for index in range(len(a_list)):
    print("index = ", index, ", number in list = ", a_list[index])
"""
index =  0 , number in list =  12
index =  1 , number in list =  3
index =  2 , number in list =  67
index =  3 , number in list =  7
index =  4 , number in list =  82
"""

for index in range(len(a_tuple)):
    print("index = ", index, ", number in tuple = ", a_tuple[index])
"""
index =  0 , number in tuple =  12
index =  1 , number in tuple =  3
index =  2 , number in tuple =  5
index =  3 , number in tuple =  15
index =  4 , number in tuple =  6
"""

两者最重要的区别是元组是不可变的:

>>> t = (10, 11, 12, 13, 14)
>>> t[0] = 1  #报错
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment

2.2 列表方法

与字符串类似,列表也支持以下的操作:

  • 长度
    len 查看列表长度:
>>> len(l)
3
  • 加法和乘法
    列表加法,相当于将两个列表按顺序连接:
>>> a = [1, 2, 3]
>>> b = [3.2, 'hello']
>>> a + b
[1, 2, 3, 3.2, 'hello']

  列表与整数相乘,相当于将列表重复相加:

>>> l * 2
[1, 2.0, 'hello', 1, 2.0, 'hello']
  • 索引和分片
    列表和字符串一样可以通过索引和分片来查看它的元素。

  索引:

>>> a = [10, 11, 12, 13, 14]
>>> a[0]
10

  反向索引:

>>> a[-1]
14

  切片:

>>> a[2:-1]
[12, 13]

  与字符串不同的是,列表可以通过索引和分片来修改。对于字符串,如果我们通过索引或者分片来修改,Python会报错:

>>> s = "hello world"
>>> # 把开头的 h 改成大写
... s[0] = 'H'
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
TypeError: 'str' object does not support item assignment

  而这种操作对于列表来说是可以的:

>>> a = [10, 11, 12, 13, 14]
>>> a[0] = 100
>>> print(a)
[100, 11, 12, 13, 14]

  这种赋值也适用于分片,例如,将列表的第2,3两个元素换掉:

>>> a[1:3] = [1, 2]
>>> a
[100, 1, 2, 13, 14]

  事实上,对于连续的分片(即步长为 1 ),Python采用的是整段替换的方法,两者的元素个数并不需要相同,例如,将 [11,12] 替换为 [1,2,3,4]:

>>> a = [10, 11, 12, 13, 14]
>>> a[1:3] = [1, 2, 3, 4]
>>> a
[10, 1, 2, 3, 4, 13, 14]

  这意味着,可以用这种方法来删除列表中一个连续的分片:

>>> a = [10, 1, 2, 11, 12]
>>> a[1:3] = []
>>> a
[10, 11, 12]

  对于不连续(间隔step不为1)的片段进行修改时,两者的元素数目必须一致:

>>> a[::2] = [1, 2, 3]
>>> a
[1, 11, 2, 13, 3]
  • 删除元素
    Python提供了删除列表中元素的方法 del

  删除列表中的第一个元素:

>>> a = [1002, 'a', 'b', 'c']
>>> del a[0]
>>> a
['a', 'b', 'c']

  删除第2到最后一个元素:

>>> a = [1002, 'a', 'b', 'c']
>>> del a[1:]
>>> a
[1002]

  删除间隔的元素:

>>> a = ['a', 1, 'b', 2, 'c']
>>> del a[::2]
>>> a
[1, 2]
  • 测试从属关系
    in 来看某个元素是否在某个序列(不仅仅是列表)中,用not in来判断是否不在某个序列中。
>>> a = [10, 11, 12, 13, 14]
>>> print(10 in a)
True
>>> print(10 not in a)
False

  也可以作用于字符串:

>>> s = 'hello world'
>>> print('he' in s)
True
>>> print('world' not in s)
False

  列表中可以包含各种对象,甚至可以包含列表:

>>> a = [10, 'eleven', [12, 13]]
>>> a[2]
[12, 13]

  a[2]是列表,可以对它再进行索引:

>>> a[2][1]
13

2.3 列表操作

列表是一系列有序的数列,有一系列自带的功能。

  • 不改变列表的操作
    1. 列表中某个元素个数count
    l.count(ob) 返回列表中元素 ob 出现的次数。
>>> a = [11, 12, 13, 12, 11]
>>> a.count(11)
2

2. 列表中某个元素位置index
l.index(ob) 返回列表中元素 ob 第一次出现的索引位置,如果 ob 不在 l 中会报错。

>>> a = [11, 12, 13, 12, 11]
>>> a.index(12)
1
  • 改变列表的操作
    1. 向列表添加单个元素
    l.append(ob) 将元素 ob 添加到列表 l 的最后。
>>> a = [10, 11, 12]
>>> a.append(11)
>>> print(a)
[10, 11, 12, 11]

append每次只添加一个元素,并不会因为这个元素是序列而将其展开:

>>> a.append([11, 12])
>>> print(a)
[10, 11, 12, 11, [11, 12]]

2. 向列表添加序列
l.extend(lst) 将序列 lst 的元素依次添加到列表 l 的最后,作用相当于 l += lst

>>> a = [10, 11, 12, 11]
>>> a.extend([1, 2])
>>> print(a)
[10, 11, 12, 11, 1, 2]

3. 插入元素
l.insert(idx, ob) 在索引 idx 处插入 ob ,之后的元素依次后移。

>>> a = [10, 11, 12, 13, 11]
>>> # 在索引 3 插入 'a'
... a.insert(3, 'a')
>>> print(a)
[10, 11, 12, 'a', 13, 11]

4. 移除元素
l.remove(ob) 会将列表中第一个出现的 ob 删除,如果 ob 不在 l中会报错。

>>> a = [10, 11, 12, 13, 11]
>>> # 移除了第一个 11
... a.remove(11)
>>> print(a)
[10, 12, 13, 11]

5. 弹出元素
l.pop(idx) 会将索引 idx 处的元素删除,并返回这个元素。

>>> a = [10, 11, 12, 13, 11]
>>> a.pop(2)
12

6. 排序
l.sort() 会将列表中的元素按照一定的规则排序:

>>> a = [10, 1, 11, 13, 11, 2]
>>> a.sort()
>>> print(a)
[1, 2, 10, 11, 11, 13]

  如果不想改变原来列表中的值,可以使用 sorted 函数:

>>> a = [10, 1, 11, 13, 11, 2]
>>> b = sorted(a)
>>> print(a);print(b)
[10, 1, 11, 13, 11, 2]
[1, 2, 10, 11, 11, 13]

7. 列表反向
l.reverse() 会将列表中的元素从后向前排列。

>>> a = [1, 2, 3, 4, 5, 6]
>>> a.reverse()
>>> print(a)
[6, 5, 4, 3, 2, 1]

  如果不想改变原来列表中的值,可以使用这样的方法:

>>> a = [1, 2, 3, 4, 5, 6]
>>> b = a[::-1]
>>> print(a);print(b)
[1, 2, 3, 4, 5, 6]
[6, 5, 4, 3, 2, 1]

2.4 字典

字典 dictionary ,在一些编程语言中也称为 hash , map ,是一种由键值对组成的数据结构。顾名思义,我们把键想象成字典中的单词,值想象成词对应的定义,那么一个词可以对应一个或者多个定义,但是这些定义只能通过这个词来进行查询。

  • 基本操作

1. 空字典
  Python 使用 {} 或者 dict() 来创建一个空的字典:

>>> a = {}
>>> a = dict()

  有了dict之后,可以用索引键值的方法向其中添加元素,也可以通过索引来查看元素的值:
2. 插入键值

>>> a["one"] = "this is number 1"
>>> a["two"] = "this is number 2"
>>> a
{'one': 'this is number 1', 'two': 'this is number 2'}

3. 查看键值

>>> a['one']
'this is number 1'

4. 更新键值

>>> a["one"] = "this is number 1, too"
>>> a
{'one': 'this is number 1, too', 'two': 'this is number 2'}

5. 初始化字典
  可以看到,Python使用key: value这样的结构来表示字典中的元素结构,事实上,可以直接使用这样的结构来初始化一个字典:

>>> b = {'one': 'this is number 1', 'two': 'this is number 2'}
>>> b['one']
'this is number 1'

6. 使用 dict() 初始化字典
  除了通常的定义方式,还可以通过 dict() 转化来生成字典:

>>> inventory = dict(
...     [('foozelator', 123),
...      ('frombicator', 18), 
...      ('spatzleblock', 34), 
...      ('snitzelhogen', 23)
...     ])
>>> inventory
{'foozelator': 123, 'spatzleblock': 34, 'snitzelhogen': 23, 'frombicator': 18}

  利用索引直接更新键值对:

>>> inventory['frombicator'] += 1
>>> inventory
{'foozelator': 123, 'spatzleblock': 34, 'snitzelhogen': 23, 'frombicator': 19}
  • 注意点

1. 字典没有顺序
  当我们 print 一个字典时,Python并不一定按照插入键值的先后顺序进行显示,因为字典中的键本身不一定是有序的。因此,Python中不能用支持用数字索引按顺序查看字典中的值,而且数字本身也有可能成为键值,这样会引起混淆。
2. 键必须是不可变的类型
  出于hash的目的,Python中要求这些键值对的键必须是不可变的,而值可以是任意的Python对象。

  • 适合作键的类型
    在不可变类型中,整数和字符串是字典中最常用的类型;而浮点数通常不推荐用来做键,因为浮点数存在精度的问题。
    有时候,也可以使用元组作为键值,例如,可以用元组做键来表示从第一个城市飞往第二个城市航班数的多少:
>>> connections[('New York', 'Seattle')] = 100
>>> connections[('Austin', 'New York')] = 200
>>> connections[('New York', 'Austin')] = 400

  元组是有序的,因此 ('New York', 'Austin')('Austin', 'New York') 是两个不同的键:

>>> connections[('Austin', 'New York')]
200
>>> connections[('New York', 'Austin')]
400
  • 字典方法

1. get 方法
  之前已经见过,用索引可以找到一个键对应的值,但是当字典中没有这个键的时候,Python会报错,这时候可以使用字典的 get 方法来处理这种情况:返回字典中键 key 对应的值,如果没有这个键,返回 default 指定的值(默认是 None。其用法如下:
                    d.get(key, default = None)

>>> a = {}
>>> a["one"] = "this is number 1"
>>> a["two"] = "this is number 2"

>>> a["three"]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: 'three'

>>> print(a.get("three"))
None

  此外可以用get方法指定默认值参数:

>>> a.get("three", "undefined")
'undefined'

2. pop 方法删除元素
pop 方法可以用来弹出字典中某个键对应的值,同时也可以指定默认参数:删除并返回字典中键 key 对应的值,如果没有这个键,返回 default 指定的值(默认是 None。其用法如下:
                    d.pop(key, default = None)
  弹出并返回值:

>>> a
{'one': 'this is number 1', 'two': 'this is number 2'}
>>> a.pop("two")
'this is number 2'
>>> a
{'one': 'this is number 1'}

  弹出不存在的键值:

>>> a.pop("two", 'not exist')
'not exist'

  与列表一样,del 函数可以用来删除字典中特定的键值对,例如:

>>> del a["one"]
>>> a
{}

3. update 方法更新字典
  之前已经知道,可以通过索引来插入、修改单个键值对,但是如果想对多个键值对进行操作,这种方法就显得比较麻烦,好在有 update 方法,其用法如下:
                    d.update(newd)
  将字典newd中的内容更新到d中去:

>>> person = {}
>>> person['first'] = "Jmes"
>>> person['last'] = "Maxwell"
>>> person['born'] = 1831
>>> person
{'first': 'Jmes', 'last': 'Maxwell', 'born': 1831}

  把'first'改成'James',同时插入'middle'的值'Clerk':

>>> person_modifications = {'first': 'James', 'middle': 'Clerk'}
>>> person.update(person_modifications)
>>> person
{'middle': 'Clerk', 'first': 'James', 'last': 'Maxwell', 'born': 1831}

4. in 查询字典中是否有该键
in 可以用来判断字典中是否有某个特定的键:

>>> barn = {'cows': 1, 'dogs': 5, 'cats': 3}
>>> 'chickens' in barn
False
>>> 'cows' in barn
True

5. keys 方法,values 方法和 items 方法
d.keys() 返回一个由所有键组成的列表;
d.values() 返回一个由所有值组成的列表;
d.items() 返回一个由所有键值对元组组成的列表。

>>> barn.keys()
dict_keys(['dogs', 'cows', 'cats'])
>>> barn.values()
dict_values([5, 1, 3])
>>> barn.items()
dict_items([('dogs', 5), ('cows', 1), ('cats', 3)])

2.5 集合

之前看到的列表和字符串都是一种有序序列,而集合 set 是一种无序的序列。因为集合是无序的,所以当集合中存在两个同样的元素的时候,Python只会保存其中的一个(唯一性);同时为了确保其中不包含同样的元素,集合中放入的元素只能是不可变的对象(确定性)。

  • 集合生成
    可以用set()函数来显示的生成空集合:
>>> a = set()

  也可以使用一个列表来初始化一个集合:

>>> a = set([1, 2, 3, 1])
>>> a
{1, 2, 3}

  集合会自动去除重复元素 1。

  可以看到,集合中的元素是用大括号{}包含起来的,这意味着可以用{}的形式来创建集合:

>>> a = {1, 2, 3, 1}
>>> a
{1, 2, 3}

  但是创建空集合的时候只能用set来创建,因为在Python中{}创建的是一个空的字典:

>>> s = {}
>>> type(s)
"""<class 'dict'>"""
  • 集合操作
    假设有这样两个集合:
a = {1, 2, 3, 4}
b = {3, 4, 5, 6}

1.并
  两个集合的并,返回包含两个集合所有元素的集合(去除重复)。
  可以用方法 a.union(b) 或者操作 a | b 实现。

>>> a.union(b)
{1, 2, 3, 4, 5, 6}
>>> b.union(a)
{1, 2, 3, 4, 5, 6}
>>> a | b
{1, 2, 3, 4, 5, 6}

2.交
  两个集合的交,返回包含两个集合共有元素的集合。
  可以用方法 a.intersection(b) 或者操作 a & b 实现。

>>> a.intersection(b)
{3, 4}
>>> b.intersection(a)
{3, 4}
>>> a & b
{3, 4}

3.差
  a 和 b 的差集,返回只在 a 不在 b 的元素组成的集合。
  可以用方法 a.difference(b) 或者操作 a - b 实现。

>>> a.difference(b)
{1, 2}
>>> a - b
{1, 2}
>>> b.difference(a)
{5, 6}
>>> b - a
{5, 6}

  注意:a - bb - a并不一样,b - a返回的是返回 b 不在 a 的元素组成的集合。

4.对称差
  a和b的对称差集,返回在a或在b中,但是不同时在a和b中的元素组成的集合。
  可以用方法 a.symmetric_difference(b) 或者操作 a ^ b 实现(异或操作符)。

>>> a.symmetric_difference(b)
{1, 2, 5, 6}
>>> b.symmetric_difference(a)
{1, 2, 5, 6}
>>> a ^ b
{1, 2, 5, 6}

5.包含关系
  假设现在有这样两个集合:

a = {1, 2, 3}
b = {1, 2}

  要判断b是不是a的子集,可以用 b.issubset(a) 方法,或者更简单的用操作 b <= a

>>> b.issubset(a)
True
>>> b <= a
True

b.issubset(a) 方法只能用来测试子集,但是操作符可以用来判断真子集:

>>> a <= a
True
>>> a < a
False
  • 集合方法

1.add 方法向集合添加单个元素
  跟列表的 append 方法类似,用来向集合添加单个元素。
                      s.add(a)
  将元素 a 加入集合 s 中。

>>> t = {1, 2, 3}
>>> t.add(5)
>>> t
{1, 2, 3, 5}

  如果添加的是已有元素,集合不改变:

>>> t.add(3)
>>> t
{1, 2, 3, 5}

2.update 方法向集合添加多个元素
  跟列表的 extend方法类似,用来向集合添加多个元素。
                      s.update(seq)
  将seq中的元素添加到s中。

>>> t.update([5, 6, 7])
>>> t
{1, 2, 3, 5, 6, 7}

3.remove 方法移除单个元素
                      s.remove(ob)
  从集合s中移除元素ob,如果不存在会报错。

>>> t.remove(1)
>>> t
{2, 3, 5, 6, 7}

>>> t.remove(10)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: 10

4.pop方法弹出元素
  由于集合没有顺序,不能像列表一样按照位置弹出元素,所以pop 方法删除并返回集合中任意一个元素,如果集合中没有元素会报错。

>>> t.pop()
2
>>> t
{3, 5, 6, 7}

>>> s = set()
>>> # 报错
... s.pop()
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
KeyError: 'pop from an empty set'

5.discard方法
  作用与 remove 一样,但是当元素在集合中不存在的时候不会报错。

>>> t = {3, 5, 6, 7}
>>> t.discard(3)
>>> t
{5, 6, 7}

>>> t.discard(10)
>>> t
{5, 6, 7}

6.difference_update方法
                      a.difference_update(b)
  从a中去除所有属于b的元素:

>>> a = {3, 5, 6, 7}
>>> b = {6, 7, 8}
>>> a.difference_update(b)
>>> a
{3, 5}

3.while和for循环

3.1 while循环

  • 基本使用
    while 语句同其他编程语言中 while 的使用方式大同小异,主要结构如下:
while condition:
    expressions

其中 condition 为判断条件,在 Python 中就是 TrueFalse 其中的一个,如果为 True, 那么将执行 exexpressions 语句,否则将跳过该 while 语句块接着往下执行。

  • 实例
    比如要打印出 0 - 9 的所有数据:
condition = 0
while condition < 10:
    print(condition)
    condition = condition + 1

  输出的结果将是 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 第一行设置 condition 的 初始值为 0,在进行 while 判断的时候 0 < 10True, 将会执行 while 内部的代码,首先先打印出该值,然后将 condition 值加 1,至此将完成一次循环;再 condition 的值与 10 进行比较,仍然为 True, 重复如上过程,至到 condiiton 等于 10 后,不满足 condition < 10 的条件(False),将不执行 while 内部的内容,所以 10 不会被打印。

  • 注意点
    在使用 while 句法的时候一定要注意在循环内部一定要修改判断条件的值,否则程序的 while 部分 将永远执行下去。
while True:
    print("I'm True")

如果这样做的话,程序将一直打印出I'm True, 要停止程序,使用 ctrl + c 终止程序。

  • 高级主题
    在 Python 中除了常规比较操作会返回 True 和 False值:
    • 小于(<)
    • 大于 (>)
    • 不大于 (<=)
    • 不小于 (>=)
    • 等于 (==)
    • 不等于 (!=)

  例如其他也会返回 True 和 False。

1. 数字
  整数和浮点数也能进行 Boolean 数据操作, 具体规则,如果该值等于 0 或者 0.0 将会返回 False 其余的返回 True

condiiton = 10
while condiiton:
    print(condiiton)
    condiiton -= 1

  输出的结果将会是 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 在这里 conditionwhile 语句中,如果该值大于0,那么将会返回为 True,执行循环内部语句,直至 condition 等于0,返回 False

2. None 类型
  如果 while 后面接着的语句数据类型 None, 将会返回 False

3. 集合类型
  在 Python 中集合类型有 list、tuple 、dict 和 set 等,如果该集合对象作为 while 判断语句, 如果集合中的元素数量为 0,那么将会返回 False, 否则返回 True

a = range(10)
while a:
    print(a[-1])
    a = a[:len(a)-1]

  上述程序将会返回 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 程序首先判断列表是否空,如果不为空,则打印出最后一个内容,然后使用切片操作去掉最后一个元素,并更新列表;如此重复,直至列表为空。

3.2 for循环

  • 基本使用
    不同编程语言都有 for 语言,在 Python 中的基本使用方法如下:
for item in sequence:
    expressions

sequence 为可迭代的对象,item 为序列中的每个对象。

  • 实例
example_list = [1,2,3,4,5,6,7,12,543,876,12,3,2,5]
for i in example_list:
    print(i)

  输出的结果为 1,2,3,4,5,6,7,12,543,876,12,3,2,5, 内容依次为 example_list 中的每一个元素。注意Python是使用缩进表示程序的结构,如果程序这样编写,

example_list = [1,2,3,4,5,6,7,12,543,876,12,3,2,5]
for i in example_list:
    print(i)
    print('inner of for')
print('outer of for')

那么每次循环都会输出 inner of for,在循环结束后,输出 outer of for 一次。

  • 进阶:range的使用
    1. range(start, stop)
    其中 start 将会是序列的起始值,stop为结束值,但是不包括该值,类似数学中的表达 [start, stop),左边为闭区间,右边为开区间。
for i in range(1, 10):
    print(i)

  上述表达将会返回1-9所有整数,但不包含10。

2. range(stop)
  如果省略了 start 那么将从 0 开始,相当于 range(0, stop)

3. range(start, stop, step)
step 代表步长。从 start 开始,依次增加 step 的值,直至等于或者大于 stop

for i in range(0,10, 5):
    print(i)

上述程序将会输出 0, 5。

  • 高级主题一:内置集合
    Python共内置了list、tuple、dict和set四种基本集合,每个集合对象都能够迭代。

1. tuple 类型

tup = ('python', 2.7, 64)
for i in tup:
    print(i)

程序将以此按行输出 ‘python’, 2.764

2. dictionary 类型

dic = {}
dic['lan'] = 'python'
dic['version'] = 2.7
dic['platform'] = 64
for key in dic:
    print(key, dic[key])

输出的结果为:platform 64lan python, version 2.7, 字典在迭代的过程中将 key 作为可迭代的对象返回。注意字典中 key 是乱序的,也就是说和插入的顺序是不一致的。如果想要使用顺序一致的字典,请使用 collections 模块中的 OrderedDict 对象。

3. set 类型

s = set(['python', 'python2', 'python3','python'])
for item in s:
    print(item)

将会输出 python, python3, python2。set 集合将会去除重复项,注意输出的结果也不是按照输入的顺序。

  • 高级主题二:迭代器
    Python 中的 for 句法实际上实现了设计模式中的迭代器模式 ,所以我们自己也可以按照迭代器的要求自己生成迭代器对象,以便在 for 语句中使用。 只要类中实现了 __iter__next 函数,那么对象就可以在 for 语句中使用。 现在创建 Fibonacci 迭代器对象,
# define a Fib class
class Fib(object):
    def __init__(self, max):
        self.max = max
        self.n, self.a, self.b = 0, 0, 1

    def __iter__(self):
        return self

    def __next__(self):
        if self.n < self.max:
            r = self.b
            self.a, self.b = self.b, self.a + self.b
            self.n = self.n + 1
            return r
        raise StopIteration()

# using Fib object
for i in Fib(5):
    print(i)

将会输出前 5 个 Fibonacci 数据 1, 1, 2, 3, 5

  • 高级主题三:生成器
    除了使用迭代器以外,Python 使用 yield 关键字也能实现类似迭代的效果,yield 语句每次执行时,立即返回结果给上层调用者,而当前的状态仍然保留,以便迭代器下一次循环调用。这样做的好处是在于节约硬件资源,在需要的时候才会执行,并且每次只执行一次。
def fib(max):
    a, b = 0, 1
    while max:
        r = b
        a, b = b, a+b
        max -= 1
        yield r

# using generator
for i in fib(5):
    print(i)

将会输出前 5 个 Fibonacci 数据 1, 1, 2, 3, 5

3.3 跳出循环

  • continue语句
    遇到 continue 的时候,程序会返回到循环的最开始重新执行。
    例如在循环中忽略一些特定的值:
values = [7, 6, 4, 7, 19, 2, 1]
for i in values:
    if i % 2 != 0:
        # 忽略奇数
        continue
    print(i/2)

  返回结果为3,2,1

  • break语句
    遇到 break 的时候,程序会跳出循环,不管循环条件是不是满足:
command_list = ['start', 
                'process', 
                'process',
                'process', 
                'stop', 
                'start', 
                'process', 
                'stop']
while command_list:
    command = command_list.pop(0)
    if command == 'stop':
        break
    print(command)

  返回结果为start,process,process,process。在遇到第一个 'stop' 之后,程序跳出循环。

  • else语句
    if 一样, while 和 for 循环后面也可以跟着 else 语句,不过要和break一起连用。
    • 当循环正常结束时,循环条件不满足, else 被执行;
    • 当循环被 break 结束时,循环条件仍然满足, else 不执行。

  不执行:

values = [7, 6, 4, 7, 19, 2, 1]
for x in values:
    if x <= 10:
        print 'Found:', x
        break
else:
    print('All values greater than 10')

输出结果: Found: 7

  执行:

values = [11, 12, 13, 100]
for x in values:
    if x <= 10:
        print 'Found:', x
        break
else:
    print('All values greater than 10')

输出结果: All values greater than 10

4.if判断

4.1 if判断

  • 基本使用
    与其他编程语言中的 if 语句一样,使用方法如下:
if condition:
    expressions

  如果 condition 的值为 True,将会执行 expressions 语句的内容,否则将跳过该语句往下执行。

  • 实例
x = 1
y = 2
z = 3
if x < y:
    print('x is less than y')

  上述代码中,if 语句的条件为 x < yTrue, 那么将执行条件内部语句,程序将输出 x is less than y。 当我们将代码修改为一下:

if x < y < z:
    print('x is less than y, and y is less than z')

在这里的条件变成了 x < y < z, 其相当于 x < y and y < z, 如果 and 两边的条件都为 True 那么才会返回 True。 注意这个用法是 python 语言特有,不鼓励大家写出这样的代码,以便其他语言的程序员能够看懂你的代码。

  • 注意点
    在 python 语言中等号的判断使用 == 而不是 =, 因为后一种是赋值语句。

4.2 if else判断

  • 基本使用
if condition:
    true_expressions
else:
    false_expressions

  当 if 判断条件为 True,执行 true_expressions 语句; 如果为 False,将执行 else 的内部的 false_expressions

  • 实例
x = 1
y = 2
z = 3
if x > y:
    print('x is greater than y')
else:
    print('x is less or equal to y')

  在这个例子中,因为 x > y 将会返回 False, 那么将执行 else 的分支内容。输出 x is less or equal to y

x = 4
y = 2
z = 3
if x > y:
    print('x is greater than y')
else:
    print('x is less or equal y')

在这里,因为 condition 条件为 True, 那么将会输出 x is greater than y

  • 高级主题
    对于从其他编程语言转过来的同学一定非常想知道 python 语言中的三目操作符怎么使用,很遗憾的是 python 中并没有类似 condition ? value1 : value2 三目操作符。然后现实中很多情况下我们只需要简单的判断来确定返回值,但是冗长的 if-else 语句似乎与简单的 python 哲学不一致。别担心,python 可以通过 if-else 的行内表达式完成类似的功能。
var = var1 if condition else var2

  可以这么理解上面这段语句,如果 condition 的值为 True, 那么将 var1 的值赋给 var;如果为 False 则将 var2 的值赋给 var

worked = True
result = 'done' if worked else 'not yet'
print(result)

  首先判断如果 workedTrue,那么将 done 字符串赋给 result,否则将 not yet 赋给 result。 结果将输出 done

4.3 if elif else判断

  • 基本使用

if condition1:
    true1_expressions
elif condition2:
    true2_expressions
elif condtion3:
    true3_expressions
elif ...
    ...
else:
    else_expressions

  如果有多个判断条件,那可以通过 elif 语句添加多个判断条件,一旦某个条件为 True,那么将执行对应的 expression。 并在之代码执行完毕后跳出该 if-elif-else 语句块,往下执行。

  • 实例
x = 4
y = 2
z = 3
if x > 1:
    print ('x > 1')
elif x < 1:
    print('x < 1')
else:
    print('x = 1')
print('finish')

  因为 x = 4 那么满足 if 的条件,则将输出 x > 1 并且跳出整个 if-elif-else 语句块,那么紧接着输出 finish。 如果将 x = -2 那么将满足 elif x < 1 这个条件,将输出 x <1, finish

5.定义功能

5.1 def 函数

  • 基本使用
def function_name(parameters):
    """function description"""
    expressions

  Python 使用 def 开始函数定义,紧接着是函数名,括号内部为函数的参数,内部为函数的具体功能实现代码,如果想要函数有返回值, 在 expressions 中的逻辑代码中用 return 返回。

  • 实例
def function():
    print('This is a function')
    a = 1+2
    print(a)

  上面我们定义了一个名字为 function 的函数,函数没有接收参数,所以括号内部为空,紧接着就是 函数的功能代码。如果执行该脚本,发现并没有输出任何输出,因为我们只定义了函数,而并没有执行函数。 这时我们在 Python 命令提示符中输入函数调用 function(), 注意这里调用函数的括号不能省略。那么函数内部的功能代码将会执行,输出结果:

>>> function()
This is a function
3

5.2 函数参数

  • 基本使用
def function_name(parameters):
    expressions

parameters 的位置就是函数的参数,在调用的时候传入即可。

  • 实例
def func(a, b):
    c = a+b
    print('the c is ', c)

  在这里定义的一个函数,其参数就是两个数值,函数的功能就是把两个参数加起来。运行脚本后,在 Python 提示符内调用函数 func, 如果不指定参数 func(), 那么将会出错; 输出 func(1, 2),将 a=1, b=2 传入函数,输出 the c is 3 。所以在调用函数时候,参数个数和位置一定要按照函数定义。如果我们忘记了函数的参数的位置,只知道各个参数的名字,可以在函数调用的过程中给指明特定的参数 func(a=1, b=2), 这样的话,参数的位置将不受影响,所以 func(b=2,a=1)是同样的效果。

5.3 函数默认参数

  • 基本使用
def function_name(para_1,...,para_n=defau_n,..., para_m=defau_m):
    expressions

  函数声明只需要在需要默认参数的地方用 = 号给定即可, 但是要注意所有的默认参数都不能出现在非默认参数的前面

  • 实例
def sale_car(price, color='red', brand='carmy', is_second_hand=True):
    print('price', price,
          'color', color,
          'brand', brand,
          'is_second_hand', is_second_hand,)

  在这里定义了一个 sale_car 函数,参数为车的属性,但除了 price 之外,像 color, brand 和 is_second_hand 都是有默认值的,如果我们调用函数 sale_car(1000), 那么与 sale_car(1000, 'red', 'carmy', True) 是一样的效果。当然也可以在函数调用过程中传入特定的参数用来修改默认参数。通过默认参数可以减轻我们函数调用的复杂度。

  • 进阶

1. 可变参数
  顾名思义,函数的可变参数是传入的参数可以变化的,1个,2个到任意个。当然可以将这些参数封装成一个list或者tuple传入,但不够pythonic。使用可变参数可以很好解决该问题,注意可变参数在函数定义不能出现在特定参数和默认参数前面,因为可变参数会吞噬掉这些参数。

def report(name, *grades):
    total_grade = 0
    for grade in grades:
        total_grade += grade
    print(name, 'total grade is ', total_grade)

  定义了一个函数,传入一个参数为 name, 后面的参数 *grades 使用了 * 修饰,表明该参数是一个可变参数,这是一个可迭代的对象。该函数输入姓名和各科的成绩,输出姓名和总共成绩。所以可以这样调用函数 report('Mike', 8, 9),输出的结果为 Mike total grade is 17, 也可以这样调用 report('Mike', 8, 9, 10),输出的结果为 Mike total grade is 27

2. 关键字参数
  关键字参数可以传入0个或者任意个含参数名的参数,这些参数名在函数定义中并没有出现,这些参数在函数内部自动封装成一个字典(dict).

def portrait(name, **kw):
    print('name is', name)
    for k,v in kw.items():
        print(k, v)

  定义了一个函数,传入一个参数 name, 和关键字参数 kw,使用了 ** 修饰。表明该参数是关键字参数,通常来讲关键字参数是放在函数参数列表的最后。如果调用参数 portrait('Mike', age=24, country='China', education='bachelor') ,输出:

name is Mike
age 24
country China
education bachelor

通过可变参数和关键字参数,任何函数都可以用 universal_func(*args, **kw)表达。

5.4 map方法生成序列

可以通过 map 的方式利用函数来生成序列:

def sqr(x): 
    return x ** 2

>>> a = [2,3,4]
>>> print(map(sqr, a))
[4, 9, 16]

其用法为:map(aFun, aSeq)
将函数 aFun 应用到序列 aSeq 上的每一个元素上,返回一个列表,不管这个序列原来是什么类型。

事实上,根据函数参数的多少,map 可以接受多组序列,将其对应的元素作为参数传入函数:

def add(x, y): 
    return x + y

>>> a = (2,3,4)
>>> b = [10,5,3]
>>> print map(add,a,b)
[12, 8, 7]

6.变量形式

6.1 局部变量

def 中, 我们可以定义一个局部变量, 这个变量 a 只能在这个功能 fun 中有效, 出了这个功能, a 这个变量就不是那个局部的 a.

def fun():
    a = 10
    print(a)
    return a+100

print(fun())

"""
10
110
"""

下面这个例子就验证了如果在 fun 外面调用 a, 会报错, 这表明外面的这个 print(a) 不能找到那个局部的 a, 只有全局变量再能在外面被调用, 比如 APPLE.

APPLY = 100 # 全局变量
def fun():
    a = 10  # 局部变量
    return a+100

print(APPLE)    # 100
print(a)    # 报错, 不能拿到一个局部变量的值

6.2 全局变量

那如何在外部也能调用一个在局部里修改了的全局变量呢. 首先我们在外部定义一个全局变量 a=None, 然后在 fun() 中声明 这个 a 是来自外部的 a. 声明方式就是 global a. 然后对这个外部的 a 修改后, 修改的效果会被施加到外部的 a 上. 所以我们将能看到运行完 fun(), a 的值从 None 变成了 20.

APPLY = 100 # 全局变量
a = None
def fun():
    global a    # 使用之前在全局里定义的 a
    a = 20      # 现在的 a 是全局变量了
    return a+100

print(APPLE)    # 100
print('a past:', a)  # None
fun()
print('a now:', a)   # 20

7.模块和包

7.1 导入 安装 更新模块

  • 导入外部模块
import time
import time as t
from time import time, localtime
from time import * 
  • 安装外部模块
$ pip install <模块名>     # 这是 python2+ 版本的用法
$ pip3 install <模块名>    # 这是 python3+ 版本的用法
  • 更新外部模块
$ pip install -U <模块名>     # 这是 python2+ 版本的用法
$ pip3 install -U <模块名>    # 这是 python3+ 版本的用法

7.2 name 属性

有时候我们想将一个 .py 文件既当作脚本,又能当作模块用,这个时候可以使用 __name__ 这个属性。

只有当文件被当作脚本执行的时候, __name__的值才会是 '__main__',所以我们可以:

假设有一个文件ex2.py,内容为:

PI = 3.1416

def sum(lst):
    """ Sum the values in a list
    """
    tot = 0
    for value in lst:
        tot = tot + value
    return tot

def add(x, y):
    " Add two values."
    a = x + y
    return a

def test():
    w = [0,1,2,3]
    assert(sum(w) == 6)
    print 'test passed.'
    
if __name__ == '__main__':
    test()

运行文件ex2输出:

"""
test passed.
"""

当作模块导入, test() 不会执行:

import ex2

但是可以使用其中的变量:

ex2.PI

"""
3.1416
"""

使用别名:

import ex2 as e2
e2.PI

"""
3.1416
"""

7.3 包

假设我们有这样的一个文件夹:

foo/

__init__.py
bar.py (defines func)
baz.py (defines zap)

这意味着 foo 是一个包,我们可以这样导入其中的内容:

from foo.bar import func
from foo.baz import zap

bar 和 baz 都是 foo 文件夹下的 .py 文件。

导入包要求:

  • 文件夹 foo 在Python的搜索路径中
  • __init__.py 表示 foo 是一个包,它可以是个空文件。

7.4 常用的标准库

  • re 正则表达式
  • copy 复制
  • math, cmath 数学
  • decimal, fraction
  • sqlite3 数据库
  • os, os.path 文件系统
  • gzip, bz2, zipfile, tarfile 压缩文件
  • csv, netrc 各种文件格式
  • xml
  • htmllib
  • ftplib, socket
  • cmd 命令行
  • pdb
  • profile, cProfile, timeit
  • collections, heapq, bisect 数据结构
  • mmap
  • threading, Queue 并行
  • multiprocessing
  • subprocess
  • pickle, cPickle
  • struct

8.class 类

8.1 class 类

  • class 定义一个类
    class 定义一个类, 后面的类别首字母推荐以大写的形式定义,比如Calculator. class可以先定义自己的属性,比如该属性的名称可以写为 name='Good Calculator'. class后面还可以跟def, 定义一个函数. 比如def add(self,x,y): 加法, 输出print(x+y). 其他的函数定义方法一样,注意这里的self是默认值.
class Calculator:       #首字母要大写,冒号不能缺
    name='Good Calculator'  #该行为class的属性
    price=18
    def add(self,x,y):
        print(self.name)
        result = x + y
        print(result)
    def minus(self,x,y):
        result=x-y
        print(result)
    def times(self,x,y):
        print(x*y)
    def divide(self,x,y):
        print(x/y)


>>> cal=Calculator()  #注意这里运行class的时候要加"()",否则调用下面函数的时候会出现错误,导致无法调用.
>>> cal.name
'Good Calculator'
>>> cal.price
18
>>> cal.add(10,20)
Good Calculator
30
>>> cal.minus(10,20)
-10
>>> cal.times(10,20)
200
>>> cal.divide(10,20)
0.5
  • 注意点
    注意定义自变量cal等于Calculator要加括号“()” ,cal=Calculator()否则运行下面函数的时候会出现错误,导致无法调用.

8.2 class 类 init功能

  • init
    __init__可以理解成初始化class的变量。可以在运行时,给初始值赋值,运行c=Calculator('bad calculator',18,17,16,15),然后调出每个初始值的值。看如下代码。
class Calculator:
    name='good calculator'
    price=18
    def __init__(self,name,price,height,width,weight):   # 注意,这里的下划线是双下划线
        self.name=name
        self.price=price
        self.h=height
        self.wi=width
        self.we=weight

>>> c=Calculator('bad calculator',18,17,16,15)
>>> c.name
'bad calculator'
>>> c.price
18
>>> c.h
17
>>> c.wi
16
>>> c.we
15

  如何设置属性的默认值, 直接在def里输入即可,如下:
    def __init__(self,name,price,height=10,width=14,weight=16):
  查看运行结果, 三个有默认值的属性,可以直接输出默认值,这些默认值可以在code中更改, 比如c.wi=17再输出c.wi就会把wi属性值更改为17.同理可推其他属性的更改方法。

class Calculator:
    name='good calculator'
    price=18
    def __init__(self,name,price,hight=10,width=14,weight=16): #后面三个属性设置默认值,查看运行
        self.name=name
        self.price=price
        self.h=hight
        self.wi=width
        self.we=weight

>>> c=Calculator('bad calculator',18)
>>> c.h
10
>>> c.wi
14
>>> c.we
16
>>> c.we=17
>>> c.we
17
  • 注意点
    注意def __init__的下划线是双下划线

9.input 输入

variable=input() 表示运行后,可以在屏幕中输入一个数字,该数字会赋值给自变量。看代码:

a_input=input('please input a number:')
print('this number is:',a_input)

'''
please input a number:12 #12 是我在硬盘中输入的数字
this number is: 12
'''

input()应用在if语句中.

在下面代码中,需要将input() 定义成整型,因为在if语句中自变量 a_input 对应的是1 and 2 整数型。输入的内容和判断句中对应的内容格式应该一致。

也可以将if语句中的1and2 定义成字符串,其中区别请读者写入代码查看。

a_input=int(input('please input a number:'))#注意这里要定义一个整数型
if a_input==1:
    print('This is a good one')
elif a_input==2:
    print('See you next time')
else:
    print('Good luck')

"""
please input a number:1   #input 1
This is a good one

please input a number:2   #input 2
See you next time

please input a number:3   #input 3 or other number
Good luck
"""

10.文件读取

10.1 转义字符

  • \n 换行命令
    定义 text 为字符串, 并查看使用 \n 和不适用 \n 的区别:
text='This is my first test. This is the second line. This the third '
print(text)  # 无换行命令

"""
This is my first test. This is the second line. This the third
"""

text='This is my first test.\nThis is the second line.\nThis the third line'
print(text)   # 输入换行命令\n,要注意斜杆的方向。注意换行的格式和c++一样

"""
This is my first test.
This is the second line.
This the third line
"""
  • \t tab 对齐
    使用 \t 能够达到 tab 对齐的效果:
text='\tThis is my first test.\n\tThis is the second line.\n\tThis is the third line'
print(text)  #延伸 使用 \t 对齐

"""
    This is my first test.
    This is the second line.
    This is the third line
"""

10.2 文件操作

  • open 读文件方式
    使用 open 能够打开一个文件, open 的第一个参数为文件名和路径 ‘my file.txt’, 第二个参数为将要以什么方式打开它, 比如 w 为可写方式. 如果计算机没有找到 ‘my file.txt’ 这个文件, w 方式能够创建一个新的文件, 并命名为 my file.txt
my_file=open('my file.txt','w')   #用法: open('文件名','形式'), 其中形式有'w':write;'r':read.
my_file.write(text)               #该语句会写入先前定义好的 text
my_file.close()                   #关闭文件
  • 给文件增加内容
    我们先保存一个已经有3行文字的 “my file.txt” 文件, 文件的内容如下:
This is my first test. 
This is the second line.
This the third line.

然后使用添加文字的方式给这个文件添加一行 “This is appended file.”, 并将这行文字储存在 append_file 里,注意\n的适用性:

append_text='\nThis is appended file.'  # 为这行文字提前空行 "\n"
my_file=open('my file.txt','a')   # 'a'=append 以增加内容的形式打开
my_file.write(append_text)
my_file.close()

"""
This is my first test.
This is the second line.
This the third line.
This is appended file.
"""
#运行后再去打开文件,会发现会增加一行代码中定义的字符串
  • 读取文件内容 file.read()
    使用 file.read() 能够读取到文本的所有内容.
file= open('my file.txt','r') 
content=file.read()  
print(content)

"""
This is my first test.
This is the second line.
This the third line.
This is appended file.    
"""
  • **按行读取 file.readline() **
    如果想在文本中一行行的读取文本, 可以使用 file.readline(), file.readline() 读取的内容和你使用的次数有关, 使用第二次的时候, 读取到的是文本的第二行, 并可以以此类推:
file= open('my file.txt','r') 
content=file.readline()  # 读取第一行
print(content)

"""
This is my first test.
"""

second_read_time=file.readline()  # 读取第二行
print(second_read_time)

"""
This is the second line.
"""
  • **读取所有行 file.readlines() **
    如果想要读取所有行, 并可以使用像 for 一样的迭代器迭代这些行结果, 我们可以使用 file.readlines(), 将每一行的结果存储在 list 中, 方便以后迭代.
file= open('my file.txt','r') 
content=file.readlines() # python_list 形式
print(content)

"""
['This is my first test.\n', 'This is the second line.\n', 'This the third line.\n', 'This is appended file.']
"""

# 之后如果使用 for 来迭代输出:
for item in content:
    print(item)
    
"""
This is my first test.

This is the second line.

This the third line.

This is appended file.
"""

11. 其他

11.1 try 错误处理

输出错误try:, except ... as ...: 看如下代码

try:
    file=open('eeee.txt','r')  #会报错的代码
except Exception as e:  # 将报错存储在 e 中
    print(e)
"""
[Errno 2] No such file or directory: 'eeee.txt'
"""

处理错误:会使用到循环语句。首先报错:没有这样的文件No such file or directory. 然后决定是否输入y, 输入y以后,系统就会新建一个文件(要用写入的类型),再次运行后,文件中就会写入ssss

try:
    file=open('eeee.txt','r+')
except Exception as e:
    print(e)
    response = input('do you want to create a new file:')
    if response=='y':
        file=open('eeee.txt','w')
    else:
        pass
else:
    file.write('ssss')
    file.close()
"""
[Errno 2] No such file or directory: 'eeee.txt'
do you want to create a new file:y

ssss  #eeee.txt中会写入'ssss'

11.2 zip lambda map

  • zip
    zip函数接受任意多个(包括0个和1个)序列作为参数,合并后返回一个tuple列表,请看示例:
a=[1,2,3]
b=[4,5,6]
ab=zip(a,b)
print(list(ab))  #需要加list来可视化这个功能
"""
[(1, 4), (2, 5), (3, 6)]
"""

  zip 中的运算

a=[1,2,3]
b=[4,5,6]
ab=zip(a,b)
print(list(ab))
for i,j in zip(a,b):
     print(i/2,j*2)
"""
0.5 8
1.0 10
1.5 12
"""
  • lambda
    lambda定义一个简单的函数,实现简化代码的功能,看代码会更好理解。
    fun = lambda x,y : x+y, 冒号前的x,y为自变量,冒号后x+y为具体运算。
fun= lambda x,y:x+y
x=int(input('x='))    #这里要定义int整数,否则会默认为字符串
y=int(input('y='))
print(fun(x,y))

"""
x=6
y=6
12
"""
  • map
    map是把函数和参数绑定在一起。
>>> def fun(x,y):
    return (x+y)
>>> list(map(fun,[1],[2]))
"""
[3]
"""
>>> list(map(fun,[1,2],[3,4]))
"""
[4,6]
"""

11.3 浅拷贝 & 深拷贝

  • id
    什么是id?一个对象的id值在CPython解释器里就代表它在内存中的地址
>>> import copy
>>> a=[1,2,3]
>>> b=a
>>> id(a)
"""
4382960392
"""
>>> id(b)
"""
4382960392
"""
>>> id(a)==id(b)    #附值后,两者的id相同,为true。
True
>>> b[0]=222222  #此时,改变b的第一个值,也会导致a值改变。
>>> print(a,b)
[222222, 2, 3] [222222, 2, 3] #a,b值同时改变
  • 浅拷贝
    当使用浅拷贝时,python只是拷贝了最外围的对象本身,内部的元素都只是拷贝了一个引用而已。看代码:
>>> import copy
>>> a=[1,2,3]
>>> c=copy.copy(a)  #拷贝了a的外围对象本身,
>>> id(c)
4383658568
>>> print(id(a)==id(c))  #id 改变 为false
False
>>> c[1]=22222   #此时,我去改变c的第二个值时,a不会被改变。
>>> print(a,c)
[1, 2, 3] [1, 22222, 3] #a值不变,c的第二个值变了,这就是copy和‘==’的不同
  • 深拷贝
    deepcopy对外围和内部元素都进行了拷贝对象本身,而不是对象的引用。
#copy.copy()

>>> a=[1,2,[3,4]]  #第三个值为列表[3,4],即内部元素
>>> d=copy.copy(a) #浅拷贝a中的[3,4]内部元素的引用,非内部元素对象的本身
>>> id(a)==id(d)
False
>>> id(a[2])==id(d[2])
True
>>> a[2][0]=3333  #改变a中内部原属列表中的第一个值
>>> d             #这时d中的列表元素也会被改变
[1, 2, [3333, 4]]


#copy.deepcopy()

>>> e=copy.deepcopy(a) #e为深拷贝了a
>>> a[2][0]=333 #改变a中内部元素列表第一个的值
>>> e
[1, 2, [3333, 4]] #因为时深拷贝,这时e中内部元素[]列表的值不会因为a中的值改变而改变
>>>

11.4 pickle 保存数据

  • pickle 保存
    pickle 是一个 python 中, 压缩/保存/提取 文件的模块. 最一般的使用方式非常简单. 比如下面就是压缩并保存一个字典的方式. 字典和列表都是能被保存的.
import pickle

a_dict = {'da': 111, 2: [23,1,4], '23': {1:2,'d':'sad'}}

# pickle a variable to a file
file = open('pickle_example.pickle', 'wb')
pickle.dump(a_dict, file)
file.close()

wb 是以写的形式打开 ‘pickle_example.pickle’ 这个文件, 然后 pickle.dump 你要保存的东西去这个打开的 file. 最后关闭 file 你就会发现你的文件目录里多了一个 ‘pickle_example.pickle’ 文件, 这就是那个字典了.

  • pickle 提取
    提取的时候相对简单点, 同样我们以读的形式打开那个文件, 然后 load 进一个 python 的变量.
# reload a file to a variable
with open('pickle_example.pickle', 'rb') as file:
    a_dict1 =pickle.load(file)

print(a_dict1)

11.5 列表推导式

循环可以用来生成列表:

values = [10, 21, 4, 7, 12]
squares = []
for x in values:
   squares.append(x**2)
print(squares)

"""
[100, 441, 16, 49, 144]
"""

列表推导式可以使用更简单的方法来创建这个列表:

values = [10, 21, 4, 7, 12]
squares = [x**2 for x in values]
print(squares)

"""
[100, 441, 16, 49, 144]
"""

还可以在列表推导式中加入条件进行筛选。
例如在上面的例子中,假如只想保留列表中不大于10的数的平方:

values = [10, 21, 4, 7, 12]
squares = [x**2 for x in values if x <= 10]
print(squares)

"""
[100, 16, 49]
"""

也可以使用推导式生成集合和字典:

square_set = {x**2 for x in values if x <= 10}
print(square_set)
square_dict = {x: x**2 for x in values if x <= 10}
print(square_dict)

"""
{16, 49, 100}
{10: 100, 4: 16, 7: 49}
"""

再如,计算上面例子中生成的列表中所有元素的和:

total = sum([x**2 for x in values if x <= 10])
print(total)

"""
165
"""

但是,Python会生成这个列表,然后在将它放到垃圾回收机制中(因为没有变量指向它),这毫无疑问是种浪费。

为了解决这种问题,与xrange()类似,Python使用产生式表达式来解决这个问题:

total = sum(x**2 for x in values if x <= 10)
print(total)

"""
165
"""

与上面相比,只是去掉了括号,但这里并不会一次性的生成这个列表。

参考资料

[1] https://morvanzhou.github.io/tutorials/python-basic/basic/
[2] http://nbviewer.jupyter.org/github/lijin-THU/notes-python/blob/master/index.ipynb

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,013评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,205评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,370评论 0 342
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,168评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,153评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,954评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,271评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,916评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,382评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,877评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,989评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,624评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,209评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,199评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,418评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,401评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,700评论 2 345

推荐阅读更多精彩内容