数据容器(Container)

在 Python 中,有个数据容器(Container)的概念。

其中包括字符串、由 range() 函数生成的等差数列、列表(List)、元组(Tuple)、集合(Set)、字典(Dictionary)。

这些容器,各有各的用处。其中又分为可变容器(Mutable)和不可变容器(Immutable)。可变的有列表、集合、字典;不可变的有字符串、range() 生成的等差数列、元组。集合,又分为 Set 和 Frozen Set;其中,Set 是可变的,Frozen Set 是不可变的。

字符串、由 range() 函数生成的等差数列、列表、元组是有序类型(Sequence Type),而集合与字典是无序的。

来源李笑来

这最后一种方式颇为神奇:

[2**x for x in range(8)]

List Comprehension。

Comprehend 这个词的意思除了 “理解” 之外,还有另外一个意思,就是 “包括、囊括” —— 这样的话,你就大概能理解这种做法为什么被称作 List Comprehension 了。中文翻译中,怎么翻译的都有,“列表生成器”、“列表生成式” 等等,都挺好。但是,被翻译成 “列表解析器”,就不太好了,给人的感觉是操作反了……

List comprehension 可以嵌套使用 for,甚至可以加上条件 if。官方文档里有个例子,是用来把两个元素并不完全相同的列表去同后拼成一个列表(下面稍作了改写):

In [4]:
import random

n = 10 

# 生成一个 n 个元素的序列,每个元素是 1~100 之间的随机数
a_list = [random.randrange(1, 100) for i in range(n)]
print(f'a_list comprehends {len(a_list)} random numbers: {a_list}')

# 从 a_list 里把偶数都挑出来
b_list = [x for x in a_list if x % 2 == 0]
print(f'... and it has {len(b_list)} even numbers: {b_list}')

a_list comprehends 10 random numbers: [52, 34, 7, 96, 33, 79, 95, 18, 37, 46]
… and it has 5 even numbers: [52, 34, 96, 18, 46]

列表的操作符

列表的操作符和字符串一样,因为它们都是有序容器。列表的操作符有:

拼接:+(与字符串不一样的地方是,不能用空格 ’ ’ 了)
复制:*
逻辑运算:in 和 not in,<、<=、>、>=、!=、==

根据索引提取列表元素

列表当然也可以根据索引操作,但由于列表是可变序列,所以,不仅可以提取,还可以删除,甚至替换。

 根据索引删除
del c_list[3]
print(c_list)           # del 是个命令,del c_list[3] 是一个语句;不能这么写:print(del c_list[3])
del c_list[5:8]         
print(c_list)

print()
# 根据索引替换
c_list[1:5:2] = ['a', 2]  # s[start:stop:step] = t,跟 range 的三个参数类似;
                         # len(t) = len([start:stop:step]) 必须为真
print(c_list)

之前提到过:

字符串常量(String Literal)是不可变有序容器,所以,虽然字符串也有一些 Methods 可用,但那些 Methods 都不改变它们自身,而是在操作后返回一个值给另外一个变量。

而对于列表这种可变容器,我们可以对它进行操作,结果是它本身被改变了。

s = 'Python'
L = list(s)
print(s)
print(L)
del L[2]
print(L) # 用 del 对 L 操作之后,L 本身少了 1 个元素
Python
['P', 'y', 't', 'h', 'o', 'n']
['P', 'y', 'h', 'o', 'n']

Methods

字符串常量和 range() 都是不可变的(Immutable);而列表则是可变类型(Mutable type),所以,它最起码可以被排序 —— 使用 sort() Method:

可变序列还有一系列可用的 Methods:a.append(),a.clear(),a.copy(),a.extend(t),a.insert(i,x),a.pop([i]),a.remove(x),a.reverse()……

# 清空序列
print()
print(a_list)
a_list.clear()
print(a_list)

print()
# 拷贝一个列表
d_list = c_list.copy()
print(d_list)
del d_list[6:8]
print(d_list)
print(c_list)             # 对一个拷贝操作,不会更改 “原件”

print()
# 演示拷贝 .copy() 与赋值 = 的不同
e_list = d_list
del e_list[6:8]
print(e_list)
print(d_list)             # 对 e_list 操作,相等于对 d_list 操作

# 在末尾追加一个列表
print()
print(a_list)
a_list.extend(c_list)      # 相当于 a_list += c_list
print(a_list)

# 在某索引位置插入一个元素
print()
print(a_list)
a_list.insert(1, 'example')   # 在索引 1 的位置插入 'example'
a_list.insert(3, 'example')   # 在索引 3 的位置插入 'example';
print(a_list)

有一个命令、两个 Methods 与删除单个元素相关联,del,a.pop([i]),a.remove(x),请注意它们之间的区别。

# 删除
print()
print(a_list)
a_list.remove('example')      # 去除 'example' 这个元素,如果有多个 'example',只删除第一个
print(a_list)

# pop() 删除并返回被删除的值

print()
print(a_list)
p = a_list.pop(2)      # 去除索引为 2 的元素,且返回元素的值,赋值给 p
print(a_list)
print(p)

来源李笑来

c = (2) # 不是元组
c
type(c) # 还是 int

d = (2,) # 这才是元组
d
a == d

但是,你可以在末尾追加元素。所以,严格意义上,对元组来讲,“不可变” 的意思是说,“当前已有部分不可变”……

In [17]:
a = 1, 
print(a)
print(id(a))
a += 3, 5
print(a)
print(id(a)) # id 并不相同 —— 实际上是在内存中另外新创建了一个元组……
(1,)
4593032496
(1, 3, 5)
4592468976

集合(Set)

集合(Set)这个容器类型与列表不同的地方在于,首先它不包含重合元素,其次它是无序的;进而,集合又分为两种,Set,可变的,Frozen Set,不可变的。

创建一个集合,用花括号 {} 把元素括起来,用 , 把元素隔开:

a = {} # 注意这样创建的是一个 dict(字典),而不是 set 集合
b = set() # 这样创建的才是空集合

Set 当然也可以进行 Comprehension:

In [22]:
a = "abcabcdeabcdbcdef"
b = {x for x in a if x not in 'abc'}
b
Out[22]:
{'d', 'e', 'f'}

将序列类型数据转换成 Set,就等于去重。当然,也可以用 in 来判断某个元素是否属于这个集合。len()、max()、min(),也都可以用来操作 Set,但 del 却不行 —— 因为 Set 中的元素没有索引(它不是有序容器)。

对于集合,有相应的操作符可以对它们进行集合运算:

并集:|
交集:&
差集:-
对称差集:^

admins = {'Moose', 'Joker', 'Joker'}
moderators = {'Ann', 'Chris', 'Jane', 'Moose', 'Zero'}

admins                 # 去重自动完成
'Joker' in admins      # Joker 是否是 admins?
'Joker' in moderators  # Joker 是否是 moderator?
admins | moderators    # admins、moderator,或者身兼两职的,即,两个角色中的所有人 in admins or moderators or both
admins & moderators    # 既是 admins 又是 moderator 的都有谁?in both admins and moderators
admins - moderators    # 是 admins 但不是 moderator 的都有谁?in admins but not in moderators
admins ^ moderators    # admins 和 moderator 中不是身兼两职的都有谁?in admins or moderator but not both

在这里插入图片描述
for key in phonebook1:
print(key, phonebook1[key])
这样也可以输出dict ,有意思

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值