2  Python 入门

点击下载本章节代码

2.1 Why Python

最受欢迎的编程语言

  • 支持性社区
  • ChatGPT等AI工具更可靠

2.2 Hello World Demo

让我们开始第一个Python程序:

1 + 1
2

Jupyter Notebook 快捷键

  • 执行单元格程序 Shift + Enter (Shift + Return on a Mac)
  • 插入新单元格 B (below) 或 A (above)
  • 删除单元格 D + D (按两次 D)
  • 保存 Ctrl + S (Cmd + S on a Mac)
  • #开始的行为注释,不会被执行

2.3 编程:让机器执行你的指令

现实生活中的指令(煎蛋步骤)

  1. 将一个鸡蛋打入小碗中,确保没有蛋壳,放在一旁备用。
  2. 在不粘锅中加入黄油或其他油脂,用中高火加热一分钟。
  3. 将鸡蛋倒入锅中,煮三到四分钟。
  4. 上桌,根据个人口味添加盐和胡椒。

编程中的指令

# 赋值给num1和num2
num1 = 37
num2 = 5

# 计算和
sum = num1 + num2

# 展示结果
print(sum)
42

A set of instructions to perform a task

2.4 数据类型

编程本质上就是在处理文字和数字。常见的数据类型比如日期、时间、货币、百分比、电话号码、邮件地址、网址等等。

字符串和数字的区别

  • 数字用来加减乘除,并且是有意义的
  • 字符串用于切片、提取一部分、粘贴一起、打印消息等等

2.5 字符串Strings介绍

  • Python 中的字符串是由文本数字符号字符组成的任意组合,并且用双引号或者单引号括起来。
  • 引号之间的所有内容都是字符串的一部分,包括空格。

例如:

  • "Hello, world"
  • "My favorite drink is Earl Grey tea"
  • "_(ツ)_!"
  • "2.99"
  • "大数据Big Data 》。!你好"

注意: 引号必须是英文的引号 " " ,而不是中文的引号 “ ”

特殊字符串

print("Hello World!")
Hello World!
type("Hello World!")
str
print("""这是一个多行字符串的实例
也可以使用换行符。""")
这是一个多行字符串的实例
也可以使用换行符。

特殊字符

  • \n换行符,例如 print("Hello\nWorld")
    • Windows系统中,会使用 \r\n(回车加换行)作为新行的标记。
  • \t 制表符; \" 双引号; \' 单引号

注意事项

函数的概念会在后面继续讲。我们可以用 """ 来创建多行字符串。

如果写成 print("Hello"World") 会出现错误:SyntaxError: EOL while scanning string literal

字符串索引切片

Python String Indexing

语法:string[start:stop:step]

a = "Python is easy"
len(a)
14
print(a[1])  # y
y
print(a[1:4])  # yth
yth
print(a[1:4:2])  # yt
yh

字符串基本操作

"Hello" in "Hello World!"
True
"hello" not in "Hello World!"
True
"hello" + " World!"
'hello World!'
"hello" * 2
'hellohello'
"hello".upper()
'HELLO'

2.6 数字类型

Python 中的数字类型有三种:整数(int)浮点数(float) 和 复数。

  • int: 3, 400, -2, 0
  • float: 3.0, 3.14, -2.5

数字运算

print (10 % 3) # Modulus
print (2 ** 3) # Exponentiation
print (10 // 3) # Floor division
1
8
3
print(3 + 2 * (1 - 1) + 2 ** 2 )
7

数字类型检查

print(type(3)) # Int
print(type(3.0)) # Float
<class 'int'>
<class 'float'>

类型转换

print(float(3)) # Int to Float
print(int(3.0)) # Float to Int
3.0
3

数字字符转换

n = 3
print(type(n))
<class 'int'>
n_str = str(n)
print(type(n_str))
<class 'str'>
s = "3.5"
print(type(s))
<class 'str'>
s_float = float(s)
print(type(s_float))
<class 'float'>

2.7 变量

  1. 给一个值 (对象 Object) 赋予一个名称以供以后使用
  2. 使用相同的名称来引用不断变化的值

变量示例

  • x = 5
  • y = "Hello, World!"

变量命名规则

  • 只能是一个词,变量名中不能够有 空格 以及 标点符号,习惯上用 _ 表示空格
  • 不能以数字开头
  • 不能使用Python保留字(关键字)e.g., False True if else import None del, etc.
  • 建议只包含 字母、数字和下划线
  • Snake Case : my_variable_name
  • Camel Case : myVariableName
  • 变量名是区分大小写的

练习:判断合法的变量名?

balance, current-balance, current balance, true, currentBalance,
current_balance, _spam, SPAM, 4account, account4, 100, total_$um, 'guanli'

注意事项

Python的变量是动态类型的,这意味着变量的数据类型是根据赋给它的值来确定的。

Python关键字: False await else import pass None break except in raise True class finally is return and continue for lambda try as def from nonlocal while assert del global not with async elif if or yield

变量赋值

num = 5
num = 32
print(num)
32
num = num + 1
print(num)
33
num = "Hello"
print(num)
Hello

2.8 字符串格式化

name = "小李"
print("你好," + name + "!")
你好,小李!

这样会出错

year = 1998
print("小李出生于" + year + "年!")

正确的方式

year = 1998
print("小李出生于" + str(year) + "年!")
小李出生于1998年!

Format string 方式

year = 1998
name = "小李"
print(f"我是{name},出生于{year}年!")
我是小李,出生于1998年!

Format String 更多例子

print(f"Isabel is {28/7} years old.")
Isabel is 4.0 years old.

格式化小数

问题: python format string 里面如何小数取整?

print(f"Isabel is {28/7:.0f} years old.")
Isabel is 4 years old.

Format String 的巧妙用法

  • 对齐:f"|{name:<10}|{name:^10}|{name:>10}|"
  • 补零:f"{number:04}"
  • 百分比:f"{percentage:.2%}"

2.9 函数

  • 函数允许你对数据执行特定 操作,并提供(或返回 return)结果。
    • len("Hello World!")
    • round(3.14159)

无返回值函数

  • 有些函数不返回结果,只是执行操作。
    • print("Hello")

自定义函数

带返回值的函数

def add(x, y):
  z = x + y * 2
  return z

无参数函数

def greet():
  print('Hello World!')

带参数函数

def greet(name):
  print(f'你好,{name}!')

greet('小李')
你好,小李!

注意事项

  • 函数也是一个对象,是一个代码块,一个过程,可以重复使用。
  • 匿名函数 lambda x: (x + 1) ** 2
  • type(greet) 可以查看函数类型

Lambda函数(可选)

lambda x: (x + 1) ** 2
<function __main__.<lambda>(x)>
f = lambda x: (x + 1) ** 2
type(f)
function

2.10 容器数据类型(container)

类型 例子
列表 list my_list = [1, 2, 3]
元组 tuple my_tuple = (1, 2, 3)
集合 set my_set = {1,3,5}
字典 dict my_dict = {'David': 25, 'Mark':30}

列表List

  • 列表是一个有序的集合,可以包含不同类型的元素。
  • 列表是可变的,可以通过索引进行修改。string不可以。

基本操作

example_list = [1, 2, 3, 4, 5]
print(example_list)
[1, 2, 3, 4, 5]
print(example_list[0])
1
print(example_list[1:3])
[2, 3]
print(example_list[::2])
[1, 3, 5]

修改列表

example_list.append(1)
example_list
[1, 2, 3, 4, 5, 1]
example_list.insert(0, 111)
example_list
[111, 1, 2, 3, 4, 5, 1]
example_list[2] = 10
example_list
[111, 1, 10, 3, 4, 5, 1]

列表练习

L = [['Apple', 'Google', 'Microsoft'],
     ['Java', 'Python', 'Ruby', 'PHP'],
     ['Adam', 'Bart', 'Lisa']]

# 打印出Apple:
# 打印出Python:
# 打印出Lisa:
解决方案:
print(L[0][0])
print(L[1][1])
print(L[2][2])
Apple
Python
Lisa

元组Tuple

example_tuple = (4,5,"test",8)
type(example_tuple)
tuple
example_tuple[0]
4
example_tuple[0] = 10

集合Set

lp = [1,2,3,4,5,5,5,5,5,5,5,5]
set(lp)
{1, 2, 3, 4, 5}
set1 = {"上证综指","深圳成指","恒生指数",
  "日经225指数","道琼斯指数"}
type(set1)
set
set2 = {"标普500指数","道琼斯指数","沪深300指数",
  "日经225指数","发过CAC40指数","德国DAX指数"}
type(set2)
set
set1 | set2 # 并集
{'上证综指',
 '发过CAC40指数',
 '德国DAX指数',
 '恒生指数',
 '日经225指数',
 '标普500指数',
 '沪深300指数',
 '深圳成指',
 '道琼斯指数'}
print(set1 & set2)
print(set1.intersection(set2))
{'日经225指数', '道琼斯指数'}
{'日经225指数', '道琼斯指数'}
print(set1 - set2) # set1对set2的差集
print(set2 - set1) # set2对set1的差集
{'深圳成指', '上证综指', '恒生指数'}
{'标普500指数', '沪深300指数', '发过CAC40指数', '德国DAX指数'}
set1.add("德国DAX指数")
set1
{'上证综指', '德国DAX指数', '恒生指数', '日经225指数', '深圳成指', '道琼斯指数'}
set1.discard("日经225指数")
set1
{'上证综指', '德国DAX指数', '恒生指数', '深圳成指', '道琼斯指数'}

字典Dict

{key1:value1, key2:value2, key3:value2 ,...}

  1. 字典中的元素必须以键(key)和值(value)的形式成对出现,也就是所谓的键-值存储;
  2. key不可以重复,但是value可以重复;
  3. key不可以修改,但是value可以修改,并且可以是任意的类型。
dict1 = {"指数名称":"沪深300",
  "证券代码":"000300",
  "交易日期":"2019-01-08",
  "涨跌幅":-0.0022} # 直接法创建
print(type(dict1))
<class 'dict'>
dict2 = {} # 间接法创建
dict2["指数名称"] = "沪深300"
dict2["证券代码"] = "000300"
dict2["交易日期"] = "2019-01-08"
dict2["涨跌幅"] = -0.0022

print(type(dict2))
<class 'dict'>
dict1.keys()
dict_keys(['指数名称', '证券代码', '交易日期', '涨跌幅'])
dict1.values()
dict_values(['沪深300', '000300', '2019-01-08', -0.0022])
dict1.items()
dict_items([('指数名称', '沪深300'), ('证券代码', '000300'), ('交易日期', '2019-01-08'), ('涨跌幅', -0.0022)])
dict1['交易日期'] = "2019-01-07"
dict1
{'指数名称': '沪深300', '证券代码': '000300', '交易日期': '2019-01-07', '涨跌幅': -0.0022}

2.11 流程控制

for循环

常用的循环对象有:

  • 容器数据类型 如listtupledictsetstr
  • range(), enumerate() 函数生成对象
names = ['Michael', 'Bob', 'Tracy']

for name in names:
  print(f'你好,{name}!')
你好,Michael!
你好,Bob!
你好,Tracy!
#进行一定目的或逻辑的for循环
result = 0
for i in range(1, 101):
    result = result + i
result
5050
grades = {'Michael': 95,
          'Bob': 75,
          'Tracy': 85}

for name, grade in grades.items():
    print(f'{name}的分数是:{grade}')
Michael的分数是:95
Bob的分数是:75
Tracy的分数是:85

布尔类型

print(True)
print(False)
# no error ? 没有引号
True
False
  • 布尔类型只有两个值:TrueFalse
print(10 == 9)
False
print(10 < 9)
False
type(10 < 9)
bool
type(True)
bool
x = 10 == 9
print(x)
False

条件判断

  • Comparison Operators: >, <, >=, <=, ==, !=

  • Membership Operators: in, not in

  • Equality Operator: and, or, not

"He" in "Hello"
True
1 in [1, 3, 3, 4]
True
3 >= 2 and 3 < 2
False

if语句

age = 17
if age >= 18:
    print('your age is', age)
    print('adult')
age = 3
if age >= 18:
    print('your age is', age)
    print('adult')
else:
    print('your age is', age)
    print('teenager')
your age is 3
teenager

注意不要少写了冒号:

age = 20

if 0<= age <= 3:
    print('your age is', age)
    print('baby')
elif 3< age < 18:
    print('your age is', age)
    print('teenager')
else:
    print('your age is', age)
    print('adult')
your age is 20
adult

注意: None、[]、''、0与False功效几乎完全等同!

如果condition为None、[]、''、0、False,dosomething是不执行的!

循环控制关键字

  • break: 终止当前循环,且跳出整个循环
  • continue: 终止当次循环,跳出该次循环,直接执行下一次循环
  • pass 不执行任何操作,一般用于占位
  • else: 当 for 循环正常执行完毕(即没有通过 break 语句提前结束)时,else 块会被执行
r_list = [-0.0137, 0.024, 0.0061, -0.0022,
  0.0101, -0.0087, 0.0196, 0.0002, -0.0055 ]

for i in r_list:
    if i > 0.02:
        break
    print("收益率数据:",i)
收益率数据: -0.0137
for i in r_list:
    if i < 0:
        continue
    print("非负收益率数据:", i)
非负收益率数据: 0.024
非负收益率数据: 0.0061
非负收益率数据: 0.0101
非负收益率数据: 0.0196
非负收益率数据: 0.0002
for i in r_list:
    if i < 0:
        pass # 涨跌幅数据为负数时,不执行任何操作
    else:
        print("非负收益率数据:",i)
非负收益率数据: 0.024
非负收益率数据: 0.0061
非负收益率数据: 0.0101
非负收益率数据: 0.0196
非负收益率数据: 0.0002
for i in range(5):
    if i == 6:
        print(f"Found {i}")
        break
else:
    print("Not found")
Not found

while循环

n = 1
while n <= 5:
    print(n)
    n = n + 1
print('END')
1
2
3
4
5
END
n = 0
while True:
  n = n + 1
  print(n)
  if n >= 5:
     break
1
2
3
4
5

2.12 模块和包

包Package

  • Python有一些自带的packages,如os, pathlib, requests
  • 还可以通过pip安装更多的packages
    • 在线安装: pip install 库名
    • 离线安装: 下载.whl文件,然后 pip install 库文件.whl
%pip install --upgrade pip
%pip config set global.index-url https://mirrors.tuna.tsinghua.edu.cn/pypi/web/simple
%pip install dfply
import os
os.getcwd()
'/Users/xinlu/_project/AI4MPAcc-Course'
import pandas as pd
pd.DataFrame()
from os import getcwd
getcwd()
'/Users/xinlu/_project/AI4MPAcc-Course'
from os import getcwd as pwd
pwd()
'/Users/xinlu/_project/AI4MPAcc-Course'

自己的模块Module

2.13 错误处理

  • 如果代码中遇到 错误Error ,那么程序会在 错误 所在的代码行停止。而错误后面的代码将无法执行。
  • tryexcept 语句
a = 10
nums = [3,4,5,2,0,1,7,8]
for b in nums:
    print(a, b, a/b)
print("继续")
a = 10
nums = [3,4,5,2,0,1,7,8]
for b in nums:
    try:
        print(a, b, a/b)
    except:
        pass
print("继续")
10 3 3.3333333333333335
10 4 2.5
10 5 2.0
10 2 5.0
10 1 10.0
10 7 1.4285714285714286
10 8 1.25
继续

2.14 MarkDown 基本语法

Markdown 是一种轻量级标记语言,用于格式化纯文本。

  • Jupyter notebook Markdown单元格

  • 各种 Chat Bot 的交互界面

  • 技术文档

标题

使用 # 表示标题,# 的数量表示标题的级别,最多支持六级标题。

# 一级标题
## 二级标题
### 三级标题
#### 四级标题
##### 五级标题
###### 六级标题

强调

使用 *_ 包围文字表示斜体,使用 **__ 包围文字表示粗体,使用 ~~ 包围文字表示删除线。

*斜体* 或 _斜体_

**粗体** 或 __粗体__

~~删除线~~

列表

  • 无序列表 使用 -+* 表示。
  • 有序列表 使用数字加 . 表示。
- 项目1
- 项目2
  - 子项目2.1
  - 子项目2.2

1. 项目1
2. 项目2
   1. 子项目2.1
   2. 子项目2.2

链接

使用 [文本](链接) 创建链接,使用 [文本](链接 "标题") 创建带有标题的链接。

[Google](https://www.google.com)

[Google](https://www.google.com "访问Google")

图片

使用 ![替代文字](图片链接) 插入图片。

![示例图片](https://example.com/image.jpg)

引用

使用 > 表示引用,可以嵌套使用。

> 这是一个引用
>> 这是一个嵌套引用

代码

  • 行内代码 使用反引号 ` 包围代码。
  • 代码块 使用三个反引号 ``` 或四个空格缩进代码。

`行内代码`


```python
def hello():
    print("Hello, World!")
```

分割线

使用三个或以上的 -*_ 表示分割线。


---

***
___

表格

使用 | 创建表格,使用 - 定义表头。


| 头1 | 头2 | 头3 |
| --- | --- | --- |
| 内容1 | 内容2 | 内容3 |
| 内容A | 内容B | 内容C |
头1 头2 头3
内容1 内容2 内容3
内容A 内容B 内容C

公式

使用 $ 包围公式,支持 LaTeX 语法。

inline formula $ f\left(Y_{i t}\right)+R_{i t} g\left(Y_{i t}\right)+R_{i t} D_{i t} c\left(Y_{i t}\right)+D_{i t} d\left(Y_{i t}\right) + \epsilon_{i t} $

inline formula \(f\left(Y_{i t}\right)+R_{i t} g\left(Y_{i t}\right)+R_{i t} D_{i t} c\left(Y_{i t}\right)+D_{i t} d\left(Y_{i t}\right) + \epsilon_{i t}\)

block formula

$$
X_{i t}=\underbrace{f\left(Y_{i t}\right)+R_{i t} g\left(Y_{i t}\right)+R_{i t} D_{i t} c\left(Y_{i t}\right)+D_{i t} d\left(Y_{i t}\right)}_{=m\left(Y_{i t}, R_{i t}\right)}+\epsilon_{i t},
$$

\[ X_{i t}=\underbrace{f\left(Y_{i t}\right)+R_{i t} g\left(Y_{i t}\right)+R_{i t} D_{i t} c\left(Y_{i t}\right)+D_{i t} d\left(Y_{i t}\right)}_{=m\left(Y_{i t}, R_{i t}\right)}+\epsilon_{i t}, \]

Markdown Display

from IPython.display import display, Markdown
display(Markdown("### 测试三级标题"))
for x in range(5):
    # Print in Markdown format
    display(Markdown(f"${x}^2$ <red style='color:red'> = </red> **{x**2}**"))

Makrdown 编辑器