python学习手册:学习笔记3--Numeric Types
博客专区 > fzyz_sb 的博客 > 博客详情
  python学习手册:学习笔记3--Numeric Types
fzyz_sb 发表于3年前
  python学习手册:学习笔记3--Numeric Types
  • 发表于 3年前
  • 阅读 54
  • 收藏 0
  • 点赞 0
  • 评论 0

腾讯云 技术升级10大核心产品年终让利>>>   

1. Numeric Type Basics

    在python中,数值类型代表的并非只是数字,而是一系列相似类型的集合.具体如下:

1. 整型和浮点型对象

2. 复数对象

3. 十进制:固定精度对象

4. 分数:有理数对象

5. 集合:数值类型操作的集合

6. 布尔类型

7. 内建函数和模块:round,math,random等等

8. 表达式,非限制整数精度,按位运算符,十六进制,八进制和二进制.

9. 第三方扩展:容器,库.

1. Numeric Literals

    以下表格是提供了数值字面量的表式:

字面量
说明
1234,-24,0
整数
1.23, 1., 3.14e-10
浮点数
0o177(第一个是数字0,第二个是字母o),0x9ff,0b101010
八进制,十六进制和二进制
3+4j,3.0+4.0j
复数
set('spam'),{1, 2, 3, 4}
集合
Decimal('1.0'),Fraction(1, 3)
十进制和分数扩展形式
bool(x), True, False
布尔类型

2. 内建数值工具

    python提供一些列的工具来操作数值对象:

expression operators

    +, -, *, /, >>, **, &等等

built-in mathematical functions

    pow, abs, round, int, hex, bin等等

utility modules

    random, math等等.

3. python表达式

yield x: 生成器函数发送协议

lambda args: expression  匿名函数生成器

x if y else z: 如果y为true,则执行x,否则执行z

x in y, x not in y: 成员关系操作符(iterables,sets)

x is y, x is not y: 对象身份测试(判断类x是否是类y的实例,或者为y子类的实例)

(...): 元组,表达式,生成器表达式

[...]: 列表,列表操作(如列表推导式)

{...}: 字典,集合和字典推导式

2. Numbers in Action

1. 变量和基本表达式

    变量在第一次被赋值时候创建,而且必须被赋值情况后才能被使用.

>>> a = 3
>>> b = 4
>>> a + b, a * b
(7, 12)

2. 数值格式化显示

    我们可以使用%来显示字符串,并且可指定精度,或者使用format来显示:

>>> num = 1 / 3
>>> num
0.3333333333333333
>>> "%e" % num
'3.333333e-01'
>>> "%4.2f" % num
'0.33'
>>> "{0:4.2f}".format(num)
'0.33'
str函数: 以用户友好的方式显示

repr函数:以代码友好的方式显示(即如果是字符串,则提示字符串)

>>> repr("spam")
"'spam'"
>>> str('spam')
'spam'

3. 比较:正常和链式

    python支持链式比较法,例如(A < B < C)是合法的,相当于(A < B and B < C):

>>> x, y, z = 2, 4, 6
>>> x < y < z
True
>>> x < y > z
False
>>> x < z > y
True
    所以,这里通常会有一个陷阱:
>>> 1 == 2 < 3
False
    这里等价于:1 == 2 and 2 < 3,而非等价于(1 == 2) < 3.

    对于浮点型比较要格外的注意:

>>> 1.1 + 2.2 == 3.3
False
>>> 1.1 + 2.2
3.3000000000000003
>>> int(1.1 + 2.2) == int(3.3)
True
>>> float(1.1 + 2.2) == float(3.3)
False

4. 除法:Classic,Floor,and True

X / Y:

    在python2.X情况下,是执行classic触发(在python3.X中移除了classic),即会截断成整数.但是python3.X情况下,会得到浮点数.

X // Y:

    通过截断,得到整数.

支持不同的系统:

    若想在python2.X中实现"/"的3.X效果,可以进行强制类型转换:

>>> 3 / (float)(2)
1.5
floor与truncation

    对于//操作符,总是调用"truncating"除法,即直接截断,而非正常的四舍五入:

>>> import math
>>> math.floor(2.5)
2
>>> math.floor(-2.5)
-3
>>> math.trunc(2.5)
2
>>> math.trunc(-2.5)
-2
>>> -5 // 2    #对于负数来说是floor
-3
>>> 5 // 2     #对于整数来说是trunc
2

5. 整数精度

    python支持的整数精度大的惊人:

>>> len(str(2 ** 1000000))
301030

6. 十六进制,八进制,二进制:字面量和转换

>>> 0o1,0o20,0o377    #以数字0开头,后跟字母o/O
(1, 16, 255)
>>> 0x01,0x10,0xff    #以数字0开头,后跟字母x/X
(1, 16, 255)
>>> 0b1,0b10000,0b11111111  #以数字0开头,后跟字母b/B
(1, 16, 255)
    我们可以调用内建函数oct,hex,bin来显示字符串形式,通过内建函数int(第二个参数为基数)来格式化数值:
>>> oct(64), hex(64), bin(64)
('0o100', '0x40', '0b1000000')
>>> int("64"), int("100", 8), int("40", 16), int("1000000", 2)
(64, 64, 64, 64)
>>> int("0x40", 16), int("0b1000000", 2)
(64, 64)
>>> int("0x40", 8)
Traceback (most recent call last):
  File "<pyshell#54>", line 1, in <module>
    int("0x40", 8)
ValueError: invalid literal for int() with base 8: '0x40'
    我们甚至可以格式化输出数值:
>>> "{0:o},{1:x},{2:b}".format(64, 64, 64)
'100,40,1000000'
>>> "%o, %x, %x, %X" % (64, 64, 255, 255)
'100, 40, ff, FF'

7. 位操作

    python也可以进行类似C语言的位操作:

>>> x = 1
>>> x << 2
4
>>> x | 2
3
>>> x & 1
1
    我们也可以使用bit_length函数来计算位的个数:
>>> X = 99
>>> bin(X), X.bit_length(), len(bin(X)) - 2
('0b1100011', 7, 7)

8. 其他内建数值工具

>>> import math
>>> math.pi, math.e
(3.141592653589793, 2.718281828459045)
>>> math.sin(2 * math.pi / 180)
0.03489949670250097
>>> math.sqrt(144), math.sqrt(2)
(12.0, 1.4142135623730951)
>>> pow(2, 4), 2 ** 4, 2.0 ** 4.0
(16, 16, 16.0)
>>> abs(-42.0), sum((1, 2, 3, 4))
(42.0, 10)
>>> min(3, 1, 2, 3), max(3, 1, 2, 4)
(1, 4)
    而我们可以使用floor,trunc来截断数值:
>>> math.floor(2.567), math.floor(-2.567)
(2, -3)
>>> math.trunc(2.567), math.trunc(-2.567)
(2, -2)
>>> int(2.567), int(-2.567)
(2, -2)
>>> round(2.567), round(2.467), round(2.567, 2)
(3, 2, 2.57)
>>> "%.1f" % 2.567, '{0:.2f}'.format(2.567)
('2.6', '2.57')
    而以下展示了三种求开方的方法:
>>> import math
>>> math.sqrt(144)
12.0
>>> 144 ** 0.5
12.0
>>> pow(144, 0.5)
12.0
    以下展示了random模块的使用:
>>> import random
>>> random.random()
0.9235287913204357
>>> random.random()
0.5782930012165811
>>> random.randint(1, 10)
6
>>> random.randint(1, 10)
7
    我们甚至可以使用choice随机从列表选择一项,使用shuffle打乱原列表顺序:
>>> random.choice(['Life of Brian', 'Holy Grail', 'Meaning of Life'])
'Life of Brian'
>>> random.choice(['Life of Brian', 'Holy Grail', 'Meaning of Life'])
'Holy Grail'
>>> suits = ['hearts', 'clubs', 'diamonds', 'spades']
>>> random.shuffle(suits)
>>> suits
['spades', 'diamonds', 'hearts', 'clubs']
>>> random.shuffle(suits)
>>> suits
['spades', 'hearts', 'clubs', 'diamonds']

3. Other Numeric Types

1. Decimal Type

    对于浮点型有一个致命伤在于精度:

>>> 0.1 + 0.1 + 0.1 - 0.3
5.551115123125783e-17
    但是,使用Decimal模块则不会存在这样的问题:
>>> from decimal import Decimal
>>> Decimal('0.1') + Decimal('0.1') + Decimal('0.1') - Decimal('0.3')
Decimal('0.0')
>>> int(Decimal('0.0'))
0
    Decimal可以自动将精度调到最大精度:
>>> Decimal('0.1') + Decimal('0.10') + Decimal('0.10') + Decimal('0.30')
Decimal('0.60')
    我们也可以使用浮点数来创建Decimal(但是貌似多此一举):
>>> Decimal(0.1) + Decimal(0.1) + Decimal(0.1) - Decimal(0.3)
Decimal('2.775557561565156540423631668E-17')
    对于特殊的Decimal操作,我们可以设定其小数点位数:
>>> import decimal
>>> decimal.Decimal(1) / decimal.Decimal(7)
Decimal('0.1428571428571428571428571429')
>>> decimal.getcontext().prec = 4
>>> decimal.Decimal(1) / decimal.Decimal(7)
Decimal('0.1429')
    但是问题来了:设定了小数点后精度,如何恢复呢?我们可以使用setcontext:
>>> decimal.setcontext(decimal.DefaultContext)
>>> decimal.Decimal('1.0') / decimal.Decimal('3.0')
Decimal('0.3333333333333333333333333333')
    我们也可以产生临时的作用域来操作精度:
>>> import decimal
>>> decimal.Decimal('1.0') / decimal.Decimal('3.0')
Decimal('0.3333333333333333333333333333')
>>> with decimal.localcontext() as ctx:
	ctx.prec = 2
	decimal.Decimal('1.0') / decimal.Decimal('3.0')

	
Decimal('0.33')
>>> decimal.Decimal('1.0') / decimal.Decimal('3.0')
Decimal('0.3333333333333333333333333333')

2. Fraction Type

    当我们操作分数的时候,Fraction类型就可以派上用场了:

>>> from fractions import Fraction
>>> x = Fraction(1, 3)
>>> y = Fraction(4, 6)
>>> x
Fraction(1, 3)
>>> y
Fraction(2, 3)
>>> print(y)
2/3
    而分数甚至也可以进行数值计算:
>>> x + y
Fraction(1, 1)
>>> x - y
Fraction(-1, 3)
>>> x * y
Fraction(2, 9)
    而我们甚至可以往Fraction传递浮点数:
>>> Fraction("0.25")
Fraction(1, 4)
>>> Fraction("0.1234")
Fraction(617, 5000)
>>> Fraction(0.1234)
Fraction(8891907104280307, 72057594037927936)
>>> 8891907104280307 / 72057594037927936
0.1234
    类似于Decimal,Fraction相对于浮点型在计算上是有优势的:
>>> 0.1 + 0.1 + 0.1 - 0.3
5.551115123125783e-17
>>> from fractions import Fraction
>>> Fraction(1, 10) + Fraction(1, 10) + Fraction(1, 10) - Fraction(3, 10)
Fraction(0, 1)
    Fraction和浮点型可以进行相对的转换(下例中*是语法,代表f是元组):
>>> (2.5).as_integer_ratio()
(5, 2)
>>> f = 2.5
>>> z = Fraction(*f.as_integer_ratio())
>>> z
Fraction(5, 2)
>>> Fraction(2.5)
Fraction(5, 2)
>>> x = Fraction(1, 3)
>>> x + z
Fraction(17, 6)
>>> float(x)
0.3333333333333333
>>> float(z)
2.5
>>> float(x + z)
2.8333333333333335
>>> Fraction.from_float(1.75)
Fraction(7, 4)
>>> x + 2.0
2.3333333333333335

3. Sets

    集合是不可更改的容器,元素在集合中只会出现一次.集合是可迭代的,通常可以用作字典的键.

集合在Python2.6X版本中的应用


>>> x = set('abcde')
>>> y = set('bdxyz')
>>> x
set(['a', 'c', 'b', 'e', 'd'])
>>> x - y
set(['a', 'c', 'e'])
>>> x | y
set(['a', 'c', 'b', 'e', 'd', 'y', 'x', 'z'])
>>> x & y
set(['b', 'd'])
>>> x > y, x < y
(False, False)
备注:集合不可比较,所以集合是无序存储的.


    我们可判断元素是否在集合中:


>>> 'e' in x
True
>>> 'e' in 'Camelot', 22 in [11, 22, 33]
(True, True)
    而集合也有对应的方法(&,|):



>>> z = x.intersection(y)
>>> z
set(['b', 'd'])
>>> z.add('SPAM')
>>> z
set(['b', 'd', 'SPAM'])
>>> z.update(set(['X', 'Y']))
>>> z
set(['Y', 'X', 'b', 'd', 'SPAM'])
>>> z.remove('b')
>>> z
set(['Y', 'X', 'd', 'SPAM'])
    并且集合是可迭代的:



>>> for item in set('abc'):
	print(item * 3)

	
aaa
ccc
bbb
    使用方法有一个好处是:方法可处理可迭代的集合,而&,|只能处理集合:



>>> x
set(['a', 'c', 'b', 'e', 'd'])
>>> x | [3, 4]

Traceback (most recent call last):
  File "<pyshell#25>", line 1, in <module>
    x | [3, 4]
TypeError: unsupported operand type(s) for |: 'set' and 'list'
>>> x.union([3, 4])
set(['a', 'c', 3, 'e', 'd', 'b', 4])
集合的不可改变性:


    对于集合来说,由于其不可改变性,所以集合的元素不能是列表或者字典,但是可以是元组(且元组中元素也必须是不可改变的).


>>> s = set([1])
>>> s
set([1])
>>> s.add([2, 3])

Traceback (most recent call last):
  File "<pyshell#41>", line 1, in <module>
    s.add([2, 3])
TypeError: unhashable type: 'list'
>>> s.add({'a' : 1})

Traceback (most recent call last):
  File "<pyshell#42>", line 1, in <module>
    s.add({'a' : 1})
TypeError: unhashable type: 'dict'
>>> s.add((2, 3))
>>> s
set([1, (2, 3)])
>>> s.add(([4, 5], 6))

Traceback (most recent call last):
  File "<pyshell#45>", line 1, in <module>
    s.add(([4, 5], 6))
TypeError: unhashable type: 'list'
python2.7X以上版本的集合推导式



>>> {x ** 2 for x in [1, 2, 3, 4]}
set([16, 1, 4, 9])
集合的优点


    集合是不允许重复的,特别适用于一些特定的场合(比如统计电话号码,身份证):


>>> L = [1, 2, 3, 2, 1, 4, 5]
>>> set(L)
set([1, 2, 3, 4, 5])
    集合可用于比较两个字符串,列表或者字典的差异:



>>> set([1, 3, 5, 7]) - set([1, 2, 4, 5, 6])
set([3, 7])
>>> set('abcdefg') - set('abdghij')
set(['c', 'e', 'f'])
>>> set(dir(bytes)) - set(dir(bytearray))
set(['__getslice__', 'format', '__mod__', '_formatter_field_name_split', 'encode', '__rmod__', '__getnewargs__', '_formatter_parser'])
    若比较两个列表是否存在相同的元素(不一定排序),则集合优于排序后比较的算法:



>>> L1, L2 = [1, 3, 5, 2, 4], [2, 5, 3, 4, 1]
>>> L1 == L2
False
>>> set(L1) == set(L2)
True
>>> sorted(L1) == sorted(L2)
True



共有 人打赏支持
粉丝 363
博文 209
码字总数 447144
×
fzyz_sb
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: