"""
Python的内置序列:
1.按类型分类:
1.容器序列:list、tuple 和 collections.deque 这些序列能存放不同类型的数据
2.扁平序列: str、bytes、bytearray、memoryview 和 array.array,这类序列只能容纳一种类型
容器序列存放的是它们包含的任意类型对象的引用,而扁平序列里存放的是值而不是引用。扁平序列其实是一段连续的内存空间。
2.按能否修改分类:
1.可变序列:list、bytearray、array.array、collections.deque 和 memoryview
2.不可变序列:tuple、str和bytes
列表推导的作用只有一个:生成列表。如果想要生成其他类型的序列,可以使用生成器表达式。
生成器表达式能节省内存开销,只有每次需要产生数据的时候,生成器表达式才会逐个产生数据,而不会先把所有数据生产出来。
"""
# 使用具名元组
from collections import namedtuple
City = namedtuple('City', 'name country population coordinates')
tokyo = City('Tokyo', 'JP', '36.933', (35.6, 139.69))
print(tokyo)
print(tokyo.country)
print(City._fields)
# 给切片命名
invoice = """
0.....6.................................40...........52...55........
1909 Pimornoi PiBrella $17.50 3 $52.50
1489 6mm Tactile Switch x20 $4.95 2 $9.50
1510 Panavise Jr. -PV-201 $28.50 1 $28.50
"""
SKU = slice(0, 6)
DESCRIPTION = slice(6, 40)
UNIT_PRICE = slice(40, 52)
QUANTITY = slice(52, 55)
ITEM_TOTAL = slice(55, None)
line_items = invoice.split('\n')[2:]
for item in line_items:
print(item[UNIT_PRICE], item[DESCRIPTION])
"""
给切片赋值,如果把切片放在赋值语句的左边,或者把它作为del操作的对象,我们就可以对序列进行嫁接,切除或就地修改操作。
注意:给切片赋值时,赋值语句的右边必须是一个可迭代的对象,即使只有单独的一个值,也要把它装换成可迭代的序列。
"""
l = list(range(10))
print(l)
l[2: 5] = [20, 30]
print(l)
del l[5: 7]
print(l)
l[3::2] = [11, 22]
print(l)
"""
对序列使用'*'
注意:如果在a * n这个语句中,序列a中的元素是其他可变对象的引用的话,就需要注意了。
如:my_list = [[]] * 3, my_list列表中包含的3个元素其实是3个引用,而且这3个引用指向的都是同一个列表。
"""
l = [1, 2, 3]
print(l * 3)
print('abc' * 3)
my_list = [[]] * 3
my_list[0].append(1)
print(my_list)
"""
当我们想要初始化一个嵌套着几个列表的列表时,最好的选择是使用列表推导
"""
board = [['_'] * 3 for i in range(3)]
# 序列增量赋值的谜题
"""
下面对元组的操作中,元组t中的元素会发生改变,因为'+='不是原子操作,即使元组不可变,但是因为列表是可变对象,
所以列表最终发生了改变。
所以:
1.不要把可变对象放在元组里面。
2.增量赋值不是一个原子操作。
"""
# t = (1, 2, [30, 40])
# t[2] += [50, 60]
# print(t)
"""
使用bisect的bisect函数在有序序列中进行元素查找,
"""
import sys
import bisect
def grade(score, breakpoints=[60, 70, 80, 90], grades='FDCBA'):
i = bisect.bisect(breakpoints, score)
return grades[i]
res = [grade(score) for score in [33, 99, 77, 70, 89, 90, 100]]
print(res)