一、python中的数值

1. python支持的数值类型

Python 支持三种不同的数值类型:

  • 整型(Int) - Python3 整型是没有限制大小的,可以当作 Long 类型使用,所以 Python3 没有 Python2 的 Long 类型。布尔型(boolean)是整型的子类。
  • 浮点型(float) - 浮点型由整数部分与小数部分组成,浮点型也可以使用科学计数法表示(2.5e2 = 2.5 x 102 = 250)
  • 复数( (complex)) - 复数由实数部分和虚数部分构成,可以用a + bj,或者complex(a,b)表示, 复数的实部a和虚部b都是浮点型。

2 算数运算符

除了基本的加减乘除,%,//,需要注意以下几个易忽略的点:

//为向小数靠拢,因此在负数时为向下取整。

print(7/2)  #除  3.5
print(7%2)  #取余  1
print(7//2) #整除 下取整 向小数靠拢   3
print(-7//2) #整除下取整 向小数靠拢   -4

3 浮点运算

floor和ceil

用法简单,不赘述。

round

round和decimal都是python中表示小数的内置函数,此部分内容多涉及到四舍五入,用法可以参考这篇博文:https://www.tr0y.wang/2019/04/08/Python%E5%9B%9B%E8%88%8D%E4%BA%94%E5%85%A5/

总结下来就是,round在精确存储时,奇进偶舍;非精确表示时,精度截断,实际存储值要小。

decimal

decimal是更精确的数值计算模块,输入最好使用字符串,且可以根据需要设定不同的进位方式。

区分以下的不同,做实验帮助理解。

decimal.getcontext().rounding = decimal.ROUND_CEILING #趋向Infinity
decimal.getcontext().rounding = decimal.ROUND_FLOOR #趋向-Infinity
decimal.getcontext().rounding = decimal.ROUND_UP #远离0
decimal.getcontext().rounding = decimal.ROUND_DOWN #趋向0

decimal.getcontext().rounding = decimal.ROUND_HALF_DOWN #五舍
decimal.getcontext().rounding = decimal.ROUND_HALF_EVEN #五趋向最接近的偶数
decimal.getcontext().rounding = decimal.ROUND_HALF_UP #五入

decimal.getcontext().rounding = decimal.ROUND_05UP #四舍六入,5保留

a = decimal.Decimal('2.135').quantize(decimal.Decimal('0.00'))
b = decimal.Decimal('2.145').quantize(decimal.Decimal('0.00'))
c = decimal.Decimal('2.155').quantize(decimal.Decimal('0.00'))
d = decimal.Decimal('2.105').quantize(decimal.Decimal('0.00'))
print(a, b, c, d)

二、 字符串处理,字符集

切片

和数组切片用法相同。

字符串的长度

最容易错的是z,要注意这里有个换行,z长度为4。

x = ("1",
     "2",
     "333")
y = ("1"
     "22"
     "333")
z = '''1
22'''
print("x:%s, y:%s, z:%s"%(len(x), len(y), len(z)))
# x:3, y:6, z:4

字符串的拼接

字符串是不可变对象,每次拼接都会生成新的对象,效率很低。
更推荐的方式是:列表拼接或io.StringIO()

strip函数

去掉前后的字符串。

a = "  yyx  xxwyyefwyy  "
print(a.strip())
print(a.strip().strip('yy'))
print(a)

# yyx  xxwyyefwyy
# x  xxwyyefw
#  yyx  xxwyyefwyy

split函数

str.split(separator, maxsplit)

这里的第二个参数当设置了maxsplit=2时,最多只会分隔两次,也就是生成3个组。

Python自带的split函数只能指定一个分割符,需要使用多个分割符时,可以使用re.split()。

其他操作

index:在str中返回第一个匹配的到的位置,如果匹配不到返回ValueError
find:在str中返回第一个匹配的到的位置,匹配不到返回-1。
rfind:与find类似,不过是从右侧开始匹配。

性能

在字符串拼接时,推荐使用format/%/join方法,最好不要使用+,+=
由于字符串是不可变对象,如果在循环中使用+累积字符串,会产生不必要的临时对象并导致二次运行时间。

三、基础数据结构(tuple/list/set/dict)及其操作

1. 不可变对象与可变对象

可变对象:list dict set
不可变对象:tuple (和str int float bool)

2. list

2.1 区分append和extend

2.2 切片

x='abcde'
x[1:2:1]= b
x[-3::] = x[-3:] = cde
x[:-2] = abc
x[::-2] = eca

2.3 性能

创建list时,最好设定固定长度,而不是不断append。

成员不变时,使用tuple代替list来节约内存。list是动态array,tuple是静态array,因此,list需要更多的内存来跟踪其成员的状态。此外,对于成员个数<=20的tuple,python会对其进行缓存,即当此tuple不再使用时,python不会立即将其占用的内存返还给操作系统,而是保留备用。

使用generator comprehension代替list comprehension。generator comprehension无需定义一个包含yield语句的函数,就可以生成一个generator,两者一个生成list,一个生成generator,在内存占用上,相差悬殊,在生成速度上,相差无几 。

enen_cnt = len([x for x in range(10) if x % 2 == 0])
enen_cnt = sum(1 for x in range(10) if x % 2 == 0)

3. set

3.1 set的基本使用

添加元素:add update,其中update可以支持输入为任何类型,比如set,list,dict。
删除元素:remove discard,在不包含元素时,前者报错,后者不报错。

thisset = set(("Google", "Runoob", "Taobao"))
thisset.add("Facebook")
print(thisset)

thisset.update({1,3})
thisset.update([1,4],[5,6])
thisset.update({'a':'aaa', 'b': 'bb'})
print(thisset)

# {'Runoob', 'Taobao', 'Facebook', 'Google'}
# {1, 3, 4, 5, 6, 'Taobao', 'a', 'Google', 'b', 'Facebook', 'Runoob'}

# s.remove(x) 将元素 x 从集合 s 中移除,如果元素不存在,则会发生错误。
# s.discard(x)如果元素不存在,不会发生错误。格式如下所示:

3.2 set的基本运算

set的运算<对应于真子集⊂,<=对应于子集⊆,issubset()同样可以判断是否子集

>对应于真包含⊃,>=对应于包含⊇,对应的内置函数是issuperset()

不相交集:isdisjoint()

3.3 set的逻辑计算:

list1 = [1, 2, 3, 4, 5, 5]
list2 = [4, 5, 6, 7, 8]
set1 = set(list1)
set2 = set(list2)
print(set1)
print(set2)

print('我是and的结果, 取后面那个',set1 and set2)
print('我是or的结果,取前面那个',set1 or set2)

print('交集为:', set1 & set2)
print('并集为:', set1 | set2)
print('差集为:', set1 - set2)
print('不同的元素为:',set1 ^ set2)

# {1, 2, 3, 4, 5}
# {4, 5, 6, 7, 8}
# 我是and的结果, 取后面那个 {4, 5, 6, 7, 8}
# 我是or的结果,取前面那个 {1, 2, 3, 4, 5}
# 交集为: {4, 5}
# 并集为: {1, 2, 3, 4, 5, 6, 7, 8}
# 差集为: {1, 2, 3}
# 不同的元素为: {1, 2, 3, 6, 7, 8}

3.4 set是无序的

解包时容易出现问题。

foo_dict = {"a": "foo", "b": "bar"}
print("{a} {b}".format(**foo_dict))

foo_tuple = "foo", "bar"
print("{0} {1}".format(*foo_tuple))

foo_list = ["foo", "bar"]
print("{0} {1}".format(*foo_list))

foo_set = {"foo", "bar"}
print("{0} {1}".format(*foo_ set))

3. tuple

可用于去重。元组的定义,可以没有括号,支持以下写法。

sap_list = 'foo', 'bar'

4. dict

4.1 字典的key是不可变对象

字典key不能为可变对象。不能为list和set,可以为tuple,str等。

a = {{1, 2, 3}:'ggggg'}
print(a)
# TypeError: unhashable type: 'set'
a = {(1, 2, 3):'ggggg'}
print(a)
# {(1, 2, 3): 'ggggg'}

4.2 字典获取

dict.get(key) 而不是 dict[key]
字典对象没有has_key方法

四、序列的运算,比较和格式化

1. 序列相加相乘:

print([1, 2] + [3, 4]) # [1, 2, 3, 4]
print([1, 2] * 3) # [1, 2, 1, 2, 1, 2]
print('abc' * 3) # abcabcabc单元素必须加逗号才是元组,否则就是单变量
print(('abc',) * 3) # ('abc', 'abc', 'abc')

2. 序列的比较:

序列对象通常可以与相同序列类型的其他对象比较。这种比较使用字典式顺序

[1,5]<[3,4,6] # True
[1,4,[5,6]]<[3,4,6] # True
[3,4,[5,6]]<[3,4,6] # typeError: '<' not supported between instances of 'list' and 'int'

3. 序列和format共用

sample_list = list('HELLO')
print ('fisrt={0[0]}, third{0[2]}'.format(sample_list))
sap_list = ['foo', 'bar'] #list
print('{0} {1}'.format(*sap_list)) #单*为迭代类型

sap_list = 'foo', 'bar' #元组tuple,元组的定义可以没有括号
print('{0} {1}'.format(*sap_list)) #单*为迭代类型

sap_list = {'foo','bar'} #set
print('{0} {1}'.format(*sap_list)) #单*为迭代类型

sap_list = {'a': 'foo', 'b': 'bar'} #字典
print('{a} {b}'.format(**sap_list)) #双*为字典类型