美文网首页Python回忆录
基础篇: 2. Python整型介绍与简单应用

基础篇: 2. Python整型介绍与简单应用

作者: 后视镜 | 来源:发表于2019-10-17 15:34 被阅读0次

入门讲了简单例子后,开始要打打基础,非常详细的基础类型和语法讲述,我就一般会略过,更多我会把以前工作上遇到过的情况和问题列出来,希望大家尽量少踩坑,这些坑都是深刻的教训啊,都是钱。也讲讲我厂的情况,出bug需要扣钱,我们事故级别分为特级、一级、二级和普通故障,扣钱针对的是奖金的扣除,每个级别分别对应的扣除百分比是全部、50%、30%和看心情。那时候我的奖金占薪酬50%,每次扣奖金就可想而知地连呼吸都痛,还会有随之而来的批斗大会,自我检讨大会,接下来的几个月都好像得了阳痿的丈夫一样,战战兢兢做着需求。

整型

int

先列关键点:

  • 数值范围: [-sys.maxint - 1, sys.maxint], 在一般64位系统上面都是[-2 ^ 63, 2 ^ 63 - 1]。
  • int()方法把字符串转换为整型,对浮点数向下取整。
  • 不会溢出,超过上面的数值范围后,自动转型为long,就算你用int()强制转换回来还是long。

int整型概念会和其他语言有些不同,所以我特别列出了它的数值范围,但它比较安全的是不会溢出自动转为long值,那岂不是可以为所欲为?对的,随便赋值都可以,只要整数,Python会帮你解决一切。下面先开始简单实操,看看int的数据类型数值范围。下面是在ipython的测试代码,如果没有ipython,写到脚本里面跑也可以:

# In冒号后面的语句才是Python语句
# Out冒号后面是输出结果

# 导入sys模块
In [1]: import sys
# 打印sys数值范围
In [2]: print(-sys.maxint-1, sys.maxint)
(-9223372036854775808, 9223372036854775807)
# 测试自动转换
In [3]: int_a = sys.maxint
# type函数查看变量int_a的类型
In [4]: type(int_a)
Out[4]: int
# 在最大值+1,就自动换为long了
In [5]: type(int_a+1)
Out[5]: long
# 强制用int()转换都不行,还是long
In [7]: type(int(int_a+1))
Out[7]: long
#把字符串转换为int
In [13]: int("1")
Out[13]: 1
# 向下取整浮点数
In [14]: int(1.1)
Out[14]: 1
In [15]: int(1.5)
Out[15]: 1
In [16]: int(1.9)
Out[16]: 1
# 尝试把字符串的浮点数直接向下取整,看下可不可以?结果是报错了,不可以的
In [17]: int("1.1")
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-17-8c4c1f183c39> in <module>()
----> 1 int("1.1")

ValueError: invalid literal for int() with base 10: '1.1'
# 尝试转换一个超过数值范围的int,可以看到不会报错,直接转换为long
In [21]: int("9223372036854775808")
Out[21]: 9223372036854775808L

上面也涉及了long和float,这两个会在下面讲,如果是想学习,最好手打一遍,用肌肉加深脑袋印象。

long

long这种类型就没什么特别了,基本和int差不多,只是数值范围无精确范围。同样也有long()函数来强制转型。初始化的时候可以数字后面强制加个l或者L,表示初始化为long型,但我更推荐用大写的L,小写的太难看了。

整型的玩法-多字段排序

在实际业务中常常遇到一些排行榜,像票数排行榜之类的。最简单就是单排序,就是票数最高的排在最前面。但往往会遇到相同票数怎么排这种问题。多字段排序表示什么意思,举个实际场景例子。我以前做的一个活动榜单叫做最受欢迎主播榜,主要是根据收礼物的价值高低排序,前100名都有对应奖金,当名次相同的时候,怎么排序就要有个依据了,例如增加送礼人数的第二排序依据。这时候可能会想,人数又相同的时候怎么办,这时候再增加一个主播等级来排序,这样的话再相同的可能性就比较低了。这时候涉及三个字段的排序:礼物价值、送礼人数、主播等级这三个。我们经常在业务使用的方法是扩大倍数然后相加,最后化为一个统一的整数来排序:

公式如下:

排序值 = 收礼价值 * 10^10 + 送礼人数 * 10^5 + 主播等级 

举个实际数据例子:

主播id 收礼价值 送礼人数 主播等级 排序值
1 1000 2000 50 10000200000050
2 1000 2000 45 10000200000045
3 1000 200 90 10000020000090

最后再对数据用sorted

In [36]: sorted([10000200000045, 10000200000050, 10000020000090], reverse=True)
Out[36]: [10000200000050, 10000200000045, 10000020000090]

方法的限制之处,这种排序方法就是把每个字段扩大一定倍数再相加,某几位代表着某个字段,像收礼价值扩大了10的10次方,这里扩大多少倍自己控制,而送礼人数扩大了10的5次方,那就代表了送礼人数只能10的5次方范围内,我用|来分割一下,可以看到送礼人数最大只能去到99999,而主播等级也是。

1000|02000|00050

如果送礼人数的数量比较大,超过了99999,那么我们可以考虑以下的调整


排序值 = 收礼价值 * 10^10 + 送礼人数 * 10^3 + 主播等级 

那么主播uid为1的数据就变成了下面的数字,收礼人数的最大值变成9999999了。

1000|0002000|050

最后这个方法,搭配Redis的sortedSet一起食用更搭。

浮点数

和其他语言基本类似,如果用来比较的话就踩大坑了。经常print出来的小数部分不是多了很小的一个0.000001(0位数不一定),就是少了。例如:

In [26]: 3.3 * 3
Out[26]: 9.899999999999999

在实际业务上应用浮点数,特别是与钱相关的,通常有以下方法:

  1. 扩大一定倍数后取整使用。
  2. 用Decimal,但性能比较差,注意要初始化Decimal使用Decimal("1.1")而不是直接Decimal(1.1)。
  3. 转成字符串比较。

谈谈这三种方法的

方法 优点 缺点
扩大倍数后取整 | 编程简单并且可以用来直接排序,性能最好 阅读困难,扩大倍数特别大的时候
用Decimal 直观易用,语言直接提供的功能 性能比较低
转成字符串比较 曲线救国,能直接比较 用起来比较麻烦,由于是字符串比较,性能还是偏低

综合三种方法,能用扩大的就扩大。不能的话,用Decimal。顺便也讲讲一些金融的处理方式。

第一种就是信用卡还款分期。像100元分三期还款,人民币单位只保留到分。

100:

1. 33.33元
2. 33.33元
3. 33.33元

那这样银行肯定亏钱,每次借你100元都亏0.01元,一般来说都最后一期都不会直接除以3来计算,而是用总额扣除已缴纳的金额得到剩余额。

100 - 33.33 - 33.33 = 33.34

第二种情况就是取款问题,用户账户是保留5位数字,例如用户有33.33999元,他取款的时候只能取33.33元,保留两位小数,然后向下取整的,最后余额0.00999元,这里对用户处理可以直接没收0.00999元,或者只是不显示,下次有新的钱进来也会累加进去,具体看策划的想法。

33.33999 - 33.33 = 0.00999元

后视镜 20191017

相关文章

网友评论

    本文标题:基础篇: 2. Python整型介绍与简单应用

    本文链接:https://www.haomeiwen.com/subject/zjtmmctx.html