Python自带的序列类型可以分为两类:
1. 容器序列:容器序列可以存储不同类型的元素,像 list,tuple,collections.deque
2. 扁平序列:扁平序列里只能存储同一类型的元素,像str,bytes,bytearray,memoryview,array.array

容器序列里存储的是对象的引用,而扁平序列里存储的是值,而不是引用。扁平序列只能存储数字,字符这样的基本类型。

序列还有一种分法就是可变和不可变:
1. 可变类型 list,bytearray,array.array,collections.deque,memoryview
2. 不可变类型 tuple,str,bytes

上图可以让我们对python的序列提供的功能有个了解。

列表推导


tshirts=[(color,size)
         for color in colors
         for size in sizes
         if(not(color=='black' and size=='L'))      
        ]
# [('black', 'S'), ('black', 'M'), ('white', 'S'), ('white', 'M'), ('white', 'L')]

上边的代码生成了一个tuple的list。这个list里表示的演示是黑和白,大小是S,M,L的T恤。但是不包括黑色大号的T恤。
可以看到列表推导还是很方便的。但是它只能生成列表。为了生成其他序列,我们用生成器表达式。

生成器表达式

当然,你可以用列表推导生成一个列表,然后用这个列表去创建一个tuple,就像这样:


t = tuple([x for x in range(10)])

这个过程会先生成一个list,然后用这个list对象构造tuple。这样有个创建list的中间过程。而生成器表达式可以省去这个中间过程。它会以迭代的方式依次产生符合要求的元素。避免了内存的浪费。而生成器表达式的定义也很简单,就是把列表推导的[ ]变成( ).


t = tuple((x for x in range(10)]))
array.array("I",(x for x in range(10)))

Tuple

Tuple 和 List的区别是Tuple不可变,一旦定义,元素的个数,位置,内容都不能被修改。它的这种特性可以给我们带来其他好处。比如我们要存储一个二维坐标信息,一个人的信息。


point = (2,4) # x轴,y轴
person = ('Mark',23,175,80) #姓名,年龄,身高,体重

由于元组的不可变性,用它来存储记录很合适。它的固定位置存放固定的信息。为了方便我们取出信息,tuple还有拆包的功能:


name,age,height,weight = person

可以一次从tuple里取出所有元素并赋值给变量。如果对于其中有些变量你并不感兴趣,可以用下划线来做一个通配符。但是下划线的个数要和tuple里的元素一一对应。


name,_,_,weight = person

只关心姓名和体重。
如果tuple元素很多,你不想用下划线一一匹配,你可以用星号来匹配其他元素:


name,*others,weight = person
print(others) # (23,175)

需要注意的是上边的others是一个元组。

NamedTuple

具名元组让元组在存储记录的功能上更近了一步。它有两个好处:
1. 它让元组每个元素有了名字。可以通过名字来获取元组中特定元素。
2. 它比普通对象省内存。因为它的字段名存在类里,一个具名元组内存占用和普通元组是一样的。


Person = collections.namedtuple("Person","name age height weight")
p = Person('Mark',23,180,89)
print(p) # Person(name='Mark', age=23, height=180, weight=89)
print(p.name) # Mark

切片

一个切片的完整形式是seq[start:end:step],表示对于一个序列,从start开始(包含),end结束(不包含),以step间隔取值,生成新的序列。start省略表示从0开始,end省略表示到结尾。step省略表示步长为1。也可以取负值,负值表示从右向左。


seq = [x for x in range(10)]
seq[2:9:2] #[2, 4, 6, 8]
seq[::2] #[0, 2, 4, 6, 8]
seq[::-1] #[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

你需要知道的是seq[::-1]其实是seq[slice(None,None,-1)]的简写形式。


s = slice(None,None,-1)
seq[s] #[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

对切片进行修改

如果序列是可以修改的。那么我们可以通过切边来修改序列。


seq = [x for x in range(10)]
del seq[2:4]
seq[2:5]=[1,2,3,4,5]

发表评论

电子邮件地址不会被公开。 必填项已用*标注

%d 博主赞过: