Python 金融编程第二版(一)(2)https://developer.aliyun.com/article/1559397
第二部分:掌握基础知识
本书的这部分内容涉及 Python 编程的基础知识。本部分涵盖的主题对于随后部分中的所有其他章节都是基础的。
这些章节按照特定主题组织,使读者可以作为参考,查找与感兴趣的主题相关的示例和详细信息:
- 第三章 关于
Python
的数据类型和数据结构 - 第四章 关于
NumPy
及其ndarray
类 - 第五章 关于
pandas
及其DataFrame
类 - 第六章 关于使用 Python 的面向对象编程(OOP)
第三章:数据类型和结构
糟糕的程序员担心代码。优秀的程序员担心数据结构及其关系。
Linus Torvalds
介绍
本章介绍了Python
的基本数据类型和数据结构。尽管Python
解释器本身已经带来了丰富多样的数据结构,但NumPy
和其他库在其中增添了宝贵的内容。
本章组织如下:
“基本数据类型”
第一节介绍了基本数据类型,如int
、float
和string
。
“基本数据结构”
下一节介绍了Python
的基本数据结构(例如list
对象)并说明了控制结构、函数式编程范式和匿名函数。
本章的精神是在涉及数据类型和结构时提供对Python
特定内容的一般介绍。如果您具备来自其他编程语言(例如C
或Matlab
)的背景,那么您应该能够轻松掌握Python
用法可能带来的差异。此处介绍的主题对于接下来的章节都是重要且基础的。
本章涵盖以下数据类型和结构:
对象类型 | 含义 | 用法/模型 |
int |
整数值 | 自然数 |
float |
浮点数 | 实数 |
bool |
布尔值 | 某种真或假 |
str |
字符串对象 | 字符、单词、文本 |
tuple |
不可变容器 | 固定的对象集合、记录 |
list |
可变容器 | 变化的对象集合 |
dict |
可变容器 | 键-值存储 |
set |
可变容器 | 唯一对象的集合 |
基本数据类型
Python
是一种动态类型语言,这意味着Python
解释器在运行时推断对象的类型。相比之下,像C
这样的编译语言通常是静态类型的。在这些情况下,对象的类型必须在编译时与对象关联。¹
整数
最基本的数据类型之一是整数,或者int
:
In [1]: a = 10 type(a) Out[1]: int
内置函数type
提供了标准和内置类型的所有对象的类型信息,以及新创建的类和对象。在后一种情况下,提供的信息取决于程序员与类存储的描述。有一句话说“Python
中的一切都是对象。”这意味着,例如,即使是我们刚刚定义的int
对象这样的简单对象也有内置方法。例如,您可以通过调用方法bit_length
来获取表示内存中的int
对象所需的位数:
In [2]: a.bit_length() Out[2]: 4
您会发现,所需的位数随我们分配给对象的整数值的增加而增加:
In [3]: a = 100000 a.bit_length() Out[3]: 17
一般来说,有很多不同的方法,很难记住所有类和对象的所有方法。高级Python
环境,如IPython
,提供了可以显示附加到对象的所有方法的制表符完成功能。您只需键入对象名称,然后跟一个点(例如,a.
),然后按 Tab 键,例如,a.*tab*
。然后,这将提供您可以调用的对象的方法集合。或者,Python
内置函数dir
提供了任何对象的完整属性和方法列表。
Python
的一个特殊之处在于整数可以是任意大的。例如,考虑谷歌数 10¹⁰⁰。Python
对于这样的大数没有问题,这些大数在技术上是long
对象:
In [4]: googol = 10 ** 100 googol Out[4]: 10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 In [5]: googol.bit_length() Out[5]: 333
大整数
Python
整数可以是任意大的。解释器会根据需要使用尽可能多的位/字节来表示数字。
整数的算术运算易于实现:
In [6]: 1 + 4 Out[6]: 5 In [7]: 1 / 4 Out[7]: 0.25 In [8]: type(1 / 4) Out[8]: float
浮点数
最后一个表达式返回通常期望的结果 0.25(在基本的 Python 2.7 中不同)。这使我们进入了下一个基本数据类型,即float
对象。在整数值后添加一个点,如1.
或1.0
,会导致Python
将对象解释为float
。涉及float
的表达式通常也返回一个float
对象:^(2)
In [9]: 1.6 / 4 Out[9]: 0.4 In [10]: type (1.6 / 4) Out[10]: float
float
稍微复杂一些,因为有理数或实数的计算机化表示通常不是精确的,而是取决于所采取的具体技术方法。为了说明这意味着什么,让我们定义另一个float
对象b
。像这样的float
对象总是内部表示为仅具有一定精度的。当向b
添加 0.1 时,这变得明显:
In [11]: b = 0.35 type(b) Out[11]: float In [12]: b + 0.1 Out[12]: 0.44999999999999996
这是因为+float
+s 在内部以二进制格式表示;也就是说,十进制数0 < n < 1通过形式为n = x 2 + y 4 + z 8 + . . .的系列表示。对于某些浮点数,二进制表示可能涉及大量元素,甚至可能是一个无限级数。然而,给定用于表示此类数字的固定位数-即表示系列中的固定项数-不准确是其结果。其他数字可以完美表示,因此即使只有有限数量的位可用,它们也会被精确地存储。考虑以下示例:
In [13]: c = 0.5 c.as_integer_ratio() Out[13]: (1, 2)
一半,即 0.5,被准确地存储,因为它有一个精确(有限)的二进制表示:
< / m i > < m n > 0 < / m n > < m o > . < / m o > < m n > 5 < / m n > < m o > = < / m o > < m f r a c > < m n > 1 < / m n > < m n > 2 < / m n > < / m f r a c > < m i > </mi> <mn>0</mn> <mo>.</mo> <mn>5</mn> <mo>=</mo> <mfrac><mn>1</mn> <mn>2</mn></mfrac> <mi> </mi><mn>0</mn><mo>.</mo><mn>5</mn><mo>=</mo><mfrac><mn>1</mn><mn>2</mn></mfrac><mi> 。然而,对于b = 0.35,我们得到的结果与期望的有理数 < / m i > < m n > 0 < / m n > < m o > . < / m o > < m n > 35 < / m n > < m o > = < / m o > < m f r a c > < m n > 7 < / m n > < m n > 20 < / m n > < / m f r a c > < m i > </mi> <mn>0</mn> <mo>.</mo> <mn>35</mn> <mo>=</mo> <mfrac><mn>7</mn> <mn>20</mn></mfrac> <mi> </mi><mn>0</mn><mo>.</mo><mn>35</mn><mo>=</mo><mfrac><mn>7</mn><mn>20</mn></mfrac><mi> 不同:
In [14]: b.as_integer_ratio() Out[14]: (3152519739159347, 9007199254740992)
精度取决于用于表示数字的位数。一般来说,所有Python
运行的平台都使用 IEEE 754 双精度标准(即 64 位)来进行内部表示。³ 这意味着相对精度为 15 位数字。
由于这个主题在金融等几个应用领域非常重要,有时需要确保数字的确切或至少是最佳可能的表示。例如,在对一大堆数字求和时,这个问题可能很重要。在这种情况下,某种类型和/或数量级别的表示误差可能导致与基准值的显著偏差。
模块decimal
提供了一个用于浮点数的任意精度对象,以及几个选项来解决使用这些数字时的精度问题:
In [15]: import decimal from decimal import Decimal In [16]: decimal.getcontext() Out[16]: Context(prec=28, rounding=ROUND_HALF_EVEN, Emin=-999999, Emax=999999, capitals=1, clamp=0, flags=[], traps=[InvalidOperation, DivisionByZero, Overflow]) In [17]: d = Decimal(1) / Decimal (11) d Out[17]: Decimal('0.09090909090909090909090909091')
您可以通过改变Context
对象的相应属性值来改变表示的精度:
In [18]: decimal.getcontext().prec = 4 ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/1.png) In [19]: e = Decimal(1) / Decimal (11) e Out[19]: Decimal('0.09091') In [20]: decimal.getcontext().prec = 50 ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/2.png) In [21]: f = Decimal(1) / Decimal (11) f Out[21]: Decimal('0.090909090909090909090909090909090909090909090909091')
低于默认精度。
高于默认精度。
如有需要,可以通过这种方式调整精度以适应手头的确切问题,并且可以处理具有不同精度的浮点对象:
In [22]: g = d + e + f g Out[22]: Decimal('0.27272818181818181818181818181909090909090909090909')
任意精度浮点数
模块decimal
提供了一个任意精度浮点数对象。在金融中,有时需要确保高精度并超越 64 位双精度标准。
布尔值
在编程中,评估比较或逻辑表达式,例如4 > 3
,4.5 <= 3.25
或(4 > 3) and (3 > 2)
,会产生True
或False
之一作为输出,这是两个重要的 Python 关键字。其他例如def
,for
或if
。Python 关键字的完整列表可在keyword
模块中找到。
In [23]: import keyword In [24]: keyword.kwlist Out[24]: ['False', 'None', 'True', 'and', 'as', 'assert', 'break', 'class', 'continue', 'def', 'del', 'elif', 'else', 'except', 'finally', 'for', 'from', 'global', 'if', 'import', 'in', 'is', 'lambda', 'nonlocal', 'not', 'or', 'pass', 'raise', 'return', 'try', 'while', 'with', 'yield']
True
和False
是bool
数据类型,代表布尔值。以下代码展示了 Python 对相同操作数应用比较操作符后生成的bool
对象。
In [25]: 4 > 3 ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/1.png) Out[25]: True In [26]: type(4 > 3) Out[26]: bool In [27]: type(False) Out[27]: bool In [28]: 4 >= 3 ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/2.png) Out[28]: True In [29]: 4 < 3 ![3](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/3.png) Out[29]: False In [30]: 4 <= 3 ![4](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/4.png) Out[30]: False In [31]: 4 == 3 ![5](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/5.png) Out[31]: False In [32]: 4 != 3 ![6](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/6.png) Out[32]: True
更大。
大于或等于。
更小。
小于或等于。
相等。
不相等。
经常,逻辑运算符被应用于bool
对象,从而产生另一个bool
对象。
In [33]: True and True Out[33]: True In [34]: True and False Out[34]: False In [35]: False and False Out[35]: False In [36]: True or True Out[36]: True In [37]: True or False Out[37]: True In [38]: False or False Out[38]: False In [39]: not True Out[39]: False In [40]: not False Out[40]: True
当然,这两种类型的运算符经常结合使用。
In [41]: (4 > 3) and (2 > 3) Out[41]: False In [42]: (4 == 3) or (2 != 3) Out[42]: True In [43]: not (4 != 4) Out[43]: True In [44]: (not (4 != 4)) and (2 == 3) Out[44]: False
其一主要应用是通过其他 Python 关键字(例如if
或while
)来控制代码流程(本章后面将有更多示例)。
In [45]: if 4 > 3: ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/1.png) print('condition true') ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/2.png) condition true In [46]: i = 0 ![3](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/3.png) while i < 4: ![4](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/4.png) print('condition true, i = ', i) ![5](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/5.png) i += 1 ![6](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/6.png) condition true, i = 0 condition true, i = 1 condition true, i = 2 condition true, i = 3
如果条件成立,则执行要跟随的代码。
如果条件成立,则执行要跟随的代码。
使用 0 初始化参数i
。
只要条件成立,就执行并重复执行后续代码。
打印文本和参数i
的值。
将参数值增加 1;i += 1
等同于i = i + 1
。
在数值上,Python 将False
赋值为 0,将True
赋值为 1。通过bool()
函数将数字转换为bool
对象时,0 给出False
,而所有其他数字给出True
。
In [47]: int(True) Out[47]: 1 In [48]: int(False) Out[48]: 0 In [49]: float(True) Out[49]: 1.0 In [50]: float(False) Out[50]: 0.0 In [51]: bool(0) Out[51]: False In [52]: bool(0.0) Out[52]: False In [53]: bool(1) Out[53]: True In [54]: bool(10.5) Out[54]: True In [55]: bool(-2) Out[55]: True
Python 金融编程第二版(一)(4)https://developer.aliyun.com/article/1559399