Python入门2

本文最后更新于:2017 年 10 月 08 日 星期日

SS::STA 2017第二次活动前半部分,关于Python入门

安全须知一

  1. Python语句以换行结束,不需要也不能毫无缘由地在一个语句后面加上 ; 。当然,凡事总有例外,如果你需要在一行中书写多个语句,那么你需要用分号间隔他们。(但是原则上,如无特殊需求,尽量使用一行书写一个语句。关于一行多句以及一句多行的问题我们往后再谈。)
  2. Python以代码的 缩进 确定层次结构(所以我们避免了 神圣的大括号之战 ),原则上同一缩进即为同一层(但我们仍然建议一个缩进为4个空格)。(所以你终于没有什么借口不缩进了吧)
  3. Python 严格区分大小写 ,包括变量名、操作符、值、函数或类名、……(所有东西),比如 Truetrue 就完全不同(但我们仍然不希望你为 true 赋值)

玩耍前的热身

一点有用的内建函数

输入输出

  • print()
  • input()

于是你终于可以写你喜欢的“Hello World”及其变体了

name = input('Your name:')
print('Hello %s!' % name)

Python2.7中 print 更像操作符,他可以不需要括号。而功能与 input() 类似的则是 raw_input()

获取帮助

  • help()

你可以通过他获取内建函数、基本数据类型和自定义类和函数的部分说明

a = 1
help(a)

# 等价于下面这个
help(int)

# 可以help的东西很多
help(abs)
help(hhh)  # 这是什么鬼
help(help)
help(str)
help(list.append)

总之你什么都可以试着help()一下

退出程序(特别是在交互式环境中)

  • exit()

你在脚本中写这个似乎没什么意义

关于代码注释

养成良好的代码习惯十分重要,而代码注释是为数不多的在代码风格之战中被较好地达成一致的部分。

而且特别幸运的是,在Python中,只有一种用于标记注释的符号,即 #

# 这是一个无聊的注释,他可以独立成行
print('Hello World!')  # 他也可以跟在语句后面
# 多行注释的每一行
# 都必须要有一个井号
# 就像这样
# 其实你也可以理解为,Python没有多行注释

一般我们建议:

  • 独立成行的注释与语句一同缩进且在井号与注释内容之间留一空格
  • 在语句后面的注释,在井号与前面的语句之间和与注释内容之间分别留两个和一个空格

就跟上面那段示例一样

初谈变量与常量

与绝大多数编程语言类似,Python的变量标识符 只能由下划线或拉丁字母开头,只能包含下划线、拉丁字母和阿拉伯数字 ,并且类似的,Python也有一些保留字

Python有一个官方库 keyword ,里面有一个保留字列表 kwlist 和一个判断是否为保留字的方法 iskeyword

import keyword
print(keyword.kwlist)  # 打印保留字列表
print(keyword.iskeyword('True'))  # 判断'True'是否为保留字

灵活的变量

在Python中变量是一个十分灵活的存在

首先他不需要显式地声明,也不需要显式地指明他的类型。他们可以简单地通过赋值运算符 = 进行创建、声明以及赋值,就像这样

a = 233  # 整数
b = 1.33  # 浮点数
c = '233'  # 字符串

一个变量的类型可以通过赋值操作符随意改变,但并不代表他们的类型很随意,其实Python有着严格的类型检查。我们可以用内建函数 type() 来获取一个变量的类型

a = 233  # a是一个整数
print(a, type(a))
# 233 <class 'int'>

a = '哈哈哈'  # a变为一个字符串
print(a, type(a))
# 哈哈哈 <class 'str'>

a = 2.33  # a又变为一个浮点数
print(a, type(a))
# 2.33 <class 'float'>

关于Python中数据类型的介绍和关于变量的更多介绍将在后面为你展现

也许你对从C语言死板的变量类型中逃离感到十分高兴,但你在不久后也许会意识到,这种高兴是多余的

常量无用论

Python里没有常量,而唯一可以阻止一个变量被重新赋值的方法就是:你自己确保他没被重新赋值

当然,好的代码习惯还是必要的,如果你的确需要用变量存储一些不打算改变的值,你可以使用大写字母变量名提醒自己(欺骗自己)

PI = 3.14159265358979323846264338327950288419716939937510

相应的,变的变量尽量不要使用大写字母开头

然而我觉得,伪装成常量的变量真的很蠢,我为什么会需要常量呢

标准类型

  • int、float、bool、str(整型、浮点型、布尔型、字符串)
  • list、tuple(列表、元组)
  • dict(字典)
  • NoneType(啥也不是)

数字

int、float

Python中整数没有太多的禁忌(精度和大小方面),但是浮点数可能比较奇怪

a = 0x1234567890ABCDE
print(a)  # 可以使用16进制表示
b = 233323332333233323332333233323332333233323332333233323332333
print(b)  # 整数在精度和大小方面都没有限制
c = 2 ** 10000
print(c)  # 运算也无近似误差

d = 2.33333333333333333333333333333333333333333333  # 浮点数的精度会受限制
print(d)
e = 2.33E100
f = 2.33E500  # 指数一般不超过308(其实一般只能用到307)
print(e)
print(f)
# 运算起来也很神奇
print(2. ** 10000)
print(0.1 + 0.2)

所以如无必要,尽量使用整数

print(2333333333333333333333333333333333333333333333333333333333333)
print(2333333333333333333333333333333333333333333333333333333333333.)

字符串

Python中有现成的字符串类型(而且比C++的好用),你不用像C那样用字符数组、字符指针来操作字符串,你只需要

a = 'Hello World!'
print(a)

Python的字符串是一段在一对单引号或双引号之间的内容

a = '233哈哈哈'
b = "233哈哈哈"
print(a == b)  # 结果当然是True,他们是一样的

print('毋庸置疑的是: "在单引号标记的字符串里使用双引号是没有问题的",其实反过来也可以')
print('但如果你既需要用双引号",又要用单引号\',那你将需要用反斜杠转义')

如果你需要使用多行文本,你可以使用 \n 换行,但其实Python提供了一种更漂亮的方法,即 使用一对三个单引号包围多行文本

a = '这是第一行\n第二行\n还有第三行\n最后,第四行'
b = '''这是第一行
第二行
还有第三行
最后,第四行'''
print(a)
print(b)

转义字符相信大家都不陌生,Python也可以使用 \ 进行转义,但是如果要输出 \ 本身,就需要给他自己转义 \\ 。某些情况下你需要非常多的 \ ,在该死的re表达式中甚至需要多次转义(用四个 \ 表示一个真正的 \ )。这样非常的蠢,所以Python还提供一种较优雅的方式

print('\\\t\\\\')
print(r'\\\t\\\\')

r 作为字符串的前缀可以使字符串内的反斜杠不转义

大家应该都玩过C的格式化输出,Python也有类似功能,但这不只能用在输出上

a = 'Hello %s!' % 'World'
print(a)

b = '%d %5d %010d' % (233, 233, 233)
print(b)

c = '%f %5.2f' % (2.33, 2.33)
print(c)

d = '%x' % 563
print(d)

他们跟C的格式很像


字符串还有很多很棒的操作,其中最好玩的就是字符串切片和”加减乘除“(其实没有‘除’和’减‘)

如果你需要按照某种规律截取字符串的一部分,那在Python中多数情况下这很简单

a = 'abcdefghijklmn'
print(a[2:5:1])  # striing[start:end:step]
print(a[:6])  # 当start为0,end为字符串长度,step为1时他们可省略,省略step时其前的冒号亦可省略

# 用负数做出更复杂的切片
print(a[::-1])
print(a[-6:-2])

还有一种和切片很像的操作,像C一样用类似数组下标的方式获取某个字符(其实仍是字符串)

a = 'abcdefghijklmn'
print(a[5])
print(a[-3])

‘加’、‘数乘’

print('233' + '有趣吗')
print('233很无聊' * 2)

列表和元组

你们都学习过C语言的‘数组’,嗯,Python也有很类似的东西,但是更智能,更有趣,那就是‘列表’(list)

和其他变量一样,列表的创建或者说声明只需要通过’赋值‘操作。

a = [1, 2, 3, 4]
# 列表是由一组包裹在方括号内的数据组成的,他们不一定要有相同的类型
b = [1, '233', True, 2.345]
# 列表可以嵌套,类似于C的‘二维数组’
c = [[1, 2, 3], [2, 3, 4], [3, 4, 5]]

列表可以通过下标访问或者切片(你一定在上面见识过字符串的切片了)

print(a[1])
print(c[0][2])
print(b[1:3])

你已经注意到了,Python的列表和C的数组有一个很大的区别,我们创建他时没有为他设置大小。因为Python解释器自动帮你完成了这些操作,解释器自动识别了数据大小并为之分配合适的内存空间。如果你足够有想法,你一定会想到

“如果他真的那么智能,那他为什么不为我动态分配内存呢,他只需要检查我要加入的或者移出的数据的大小然后为我多申请一些内存或者释放多余的内存就可以了”

嗯,Python就是这么做的。这意味Python的列表比C的数组有高得多的灵活性

a.append(5)  # 在a的末尾加入5这个元素
a += [5]  # 作用类似于上面的方法,但这种方法是合并列表,而非追加元素
a.insert(2, 2.5)  # 将2.5插入到a的第2位,其后元素后移
a.pop(3)  # 删除a中第3位的数据,其后元素前移
a.update(1, 3)
# 还有一堆操作不讲了,自己help()和Google去

扔开恼人的内存管理还是一件相当值得高兴的事情

还是想顺便提醒一下,以后别再在Python中写冒泡排序了

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

元组其实和列表很相似,不同的是列表是可变的,而元组是不可变的,他将在创建时被定格。元组不可变并不等同于存储了元组的变量不可变,上面说了,你没有任何办法阻止一个变量的重新赋值,除非你不这么做。

元组的表示和读取操作和列表很像,只不过你需要用 () 代替 []

a = (1, 2, 3, 4)
b = (1, '2', 3.0, 4, (1, 2, 3))
c = (233,)
print(a[1])
print(b[3:5][1][1])  # 切片、检索都是和列表完全一样的
print(c)  #  当元组中只有一个元素,唯一的元素后面必须写一个逗号,以消除歧义

元组不可变,但是元组可以存储可变对象

a = ([1, 2, 3],)
a.append()
a[0].append()
print(a)

关于可变和不可变对象的讨论,我们后面会讲

字典

你们都见过C的数组或者是Python的列表。如果你需要用一个“名字”(一般是字符串)而不是数字下标作为索引来存储和取用数据,你会怎么做?

一个简单显而易见的方法是,创建两个数组,一个存储所谓的“名字”一个存储值,两个数组中同一下标对应的数据就是所谓的对应的“名字”和值

char keys[1000][10];
int values[1000];

字典几乎是所有高级语言的标配,但你们在C语言中可能没有接触过(因为根本没有)。

在Python中字典是非常常用的类型

a_dict = {
    'name': '罗阳豪',
    'email': 'keyboard-l@outlook.com',
    'username': 'keyboard'
}
print(a_dict['email'])

# 解释器会报错
print(a_dict['hhh'])

# 安全做法,使用get()方法查找不确定的键
print(a_dict.get('hhh'))

# 随意增改
a_dict['hhh'] = '233'
a_dict['username'] = 'KeyboardL'
print(a_dict['hhh'], a_dict['username'])

# 删除也很容易
a_dict.pop('hhh')
print(a_dict.get('hhh'))

标准类型操作符

比较运算

操作符 功能
a < b a小于b
a > b a大于b
a <= b a小于等于b
a >= b a大于等于b
a == b a等于b
a != b a不等于b
a is b a和b是同一个对象
a is not b a和b不是同一个对象

Python2.7还能使用<>表示‘不等于’,虽然我们并不推荐这么做

逻辑运算

操作符 功能
not a a的逻辑
a and b a和b的逻辑
a or b a和b的逻辑

代数运算

操作符 功能
a + b a加b的和(加法)
a - b a减b的差(减法)
a * b a乘b的积(乘法)
a / b a除以b的商(浮点除法)
a ** b a的b次方(乘方)
a // b a除以b的商(地板除法)
a % b a除以b的余(取模)

Python2.7中 / 表现地类似于C的除法(整数相除则地板除、浮点数相除或浮点数与整数相除则为浮点除法)

再谈变量

Python的变量与C语言的变量看起来有点类似(但几乎完全不同)

强类型、动态类型

  • Python不需要显式的变量类型声明(隐式)
  • 变量的类型在赋值时确定,且可以通过赋值随意改变一个变量的类型(动态)
  • 每个变量都拥有明确的类型且不允许隐式的类型转换(强)

而C语言恰恰完全相反