目录
1. 基础数据类型补充
2. set 集合
3. 深浅拷贝
1. 基础数据类型补充
(1)join 方法
join 方法是把一个列表中的数据进行拼接, 拼接成字符串 (与 split 方法相反, split 方法是把一个字符串切割成列表)
- In [1]: l1 = ['a', 'b', 'c']
- In [2]: s1 = ''
- In [3]: for i in l1: # 如果不使用 join 方法需要自己使用循环拼接成字符串
- ...: s1 += i + '-'
- In [4]: s1.strip('-')
- Out[4]: 'a-b-c'
- In [5]: l1
- Out[5]: ['a', 'b', 'c']
- In [6]: s2 = '-'.join(l1) # 使用 join 方法可以直接把字符串拼接
- In [7]: s2
- Out[7]: 'a-b-c'
(2) 列表和字典的删除及类型转换
对于列表和字典的删除, 有一个需要注意的地方, 我们先来看个例子:
- In [10]: l2 = [ 'a', 'b', 'c', 'e', 'f' ]
- In [11]: for i in l2:
- ...: l2.remove(i)
- In [12]: l2
- Out[12]: ['b', 'e']
- In [13]:
上面的例子中是遍历列表 l2 并循环删除列表中的元素, 但是最后打印时还存在 2 个元素'b'和'e', 为什么这两个元素没有被删除, 分析如下:
首次遍历列表时, i 的值为'a', 然后在列表中把元素删除后, 列表中后面的索引位置都往前移动了一位, 此时索引为 0 的位置的值为'b'
第二次次遍历时, 取到索引为 1 的元素是'c', 也就是在列表中把'c'删除了, 然后后面的索引又往前移动了
第三次循环时 i 的值为'f', 把元素'f'删除后, 循环结束, 于是最后还剩下了 2 个元素
从上面的分析来看, 我们可以得出: 在循环遍历列表时, 不应该去删除列表的元素, 否则后续的程序可能出现意料之外的错误; 如果需要删除多个元素可以使用下面这种方法:
- In [19]: l2 = [ 'a', 'b', 'c', 'e', 'f' ]
- In [20]: del_l2 = []
- In [21]: for i in l2: # 遍历列表, 把要删除的元素添加到另一个列表中, 然后再对列表进行删除
- ...: del_l2.append(i)
- In [22]: for i in del_l2:
- ...: l2.remove(i)
- In [23]: l2
- Out[23]: []
- In [24]:
然后我们再来看下字典遍历时的问题:
- In [24]: d1 = {'a':1, 'b':2}
- In [25]: for k in d1:
- ...: del d1[k]
- ---------------------------------------------------------------------------
- RuntimeError Traceback (most recent call last)
- <ipython-input-25-a77d5961c011> in
- ----> 1 for k in d1:
- 2 del d1[k]
- RuntimeError: dictionary changed size during iteration
- In [26]:
从上面的结果可以看出, 字典在遍历的时候不允许做删除操作 (RuntimeError: dictionary changed size during iteration), 要删除时跟列表一样, 把要删除的元素的 key 保存在列表中, 循环结束后再删除.
(3) 字典的 fromkey 方法及数据类型转换
fromkey 方法
dict 中的 fromkey(), 可以帮我们通过 list 来创建? 个 dict:
- In [26]: dict.fromkeys('abc', 100)
- Out[26]: {
- 'a': 100, 'b': 100, 'c': 100
- }
- In [27]: dict.fromkeys('abc', [100, 200, 300])
- Out[27]: {
- 'a': [100, 200, 300], 'b': [100, 200, 300], 'c': [100, 200, 300]
- }
- In [28]: d2 = dict.fromkeys('abc', 100)
- In [29]: d2
- Out[29]: {
- 'a': 100, 'b': 100, 'c': 100
- }
- In [30]: d3 = dict.fromkeys('abc', [100, 200, 300])
- In [31]: d3
- Out[31]: {
- 'a': [100, 200, 300], 'b': [100, 200, 300], 'c': [100, 200, 300]
- }
fromkey 方法接收两个参数, 第一个是一个可迭代的数据, 迭代出的每个元素作为字典的 key, 第二个参数作为字典 value, 但是这里要注意的是, 如果第二个参数是一个可变的数据类型, 只要修改其中一个值那么其他的值也会被修改:
- In [32]: d3['a'].pop()
- Out[32]: 300
- In [33]: d3
- Out[33]: {
- 'a': [100, 200], 'b': [100, 200], 'c': [100, 200]
- }
数据类型的转换
元组 => 列表 list(tuple)
列表 => 元组 tuple(list)
- list=>str str.join(list)
- str=>list str.split()
转换成 False 的数据:
0,'',None,[],(),{},set() ==> False
不为空 ===> True
2. set 集合
set 中的元素是不重复的.? 序的,?? 的元素必须是可 hash 的 (int, str, tuple,bool), 我们可以这样来记: set 就是 dict 类型的数据但
是不保存 value, 只保存 key,set 也?{} 表?.
set 中的元素是不重复的, 且? 序的:
- In [34]: s1 = {
- 'a', 'a', 'b', 'b', 'c'
- }
- In [35]: s1
- Out[35]: {
- 'a', 'b', 'c'
- }
- In [36]: s2 = {
- 1, 2, [11, 22]
- } # set 集合中的元素必须是可 hash 的, 但是 set 本身是不可 hash 的
- ---------------------------------------------------------------------------
- TypeError Traceback (most recent call last)
- <ipython-input-36-e5e6f226f8af> in
- ----> 1 s2 = {
- 1, 2, [11, 22]
- }
- TypeError: unhashable type: 'list'
- In [37]:
使用元素唯一性的这个特性, 可以对对数据去重处理:
- In [39]: l1 = [1, 2, 3, 2, 2, 3]
- In [40]: l1
- Out[40]: [1, 2, 3, 2, 2, 3]
- In [41]: set(l1)
- Out[41]: {
- 1, 2, 3
- }
- In [42]:
字典的方法
add 添加一个元素
clear 清空元素
pop 随机删除
remove 删除指定元素
update 对集合进行更新
union 并集运算
difference 差集运算
intersection 交集运算
symmetric_difference 反交集运算
issubset 子集
issuperset 超集
3. 深浅拷贝
(1) 赋值操作
- In [44]: a = [1, 2, 3, 4]
- In [45]: b = a
- In [46]: a.append(10)
- In [47]: a, b
- Out[47]: ([1, 2, 3, 4, 10], [1, 2, 3, 4, 10])
- In [48]: c = {
- 'a':1, 'b':2
- }
- In [49]: d = c
- In [50]: d['c'] = 5
- In [51]: d
- Out[51]: {
- 'a': 1, 'b': 2, 'c': 5
- }
- In [52]: c
- Out[52]: {
- 'a': 1, 'b': 2, 'c': 5
- }
- In [53]:
对于 list, set, dict 来说, 直接赋值. 其实是把内存地址交给变量. 并不是复制? 份内容. 所以当列表 a 变了后列表 b 也跟着变了, 字典也是一样.
(2) 浅拷贝
- In [53]: l1
- Out[53]: [1, 2, 3, 2, 2, 3]
- In [54]: l2 = l1.copy()
- In [55]: l2
- Out[55]: [1, 2, 3, 2, 2, 3]
- In [56]: l1.append('SEL')
- In [57]: print(l1, l2)
- [1, 2, 3, 2, 2, 3, 'SEL'] [1, 2, 3, 2, 2, 3]
- In [58]:
从上面的例子可以看出, 浅复制 (使用 copy 方法) 会把列表 l1 的内容赋值一份给 l2, 此时修改 l1 的内容并不会影响列表 l2 的内容, 下面的图可以看出变量存放再内存的情况:
- In [61]: l3 = l2.copy()
- In [62]: l3
- Out[62]: [1, 2, [3, 'SEL']]
- In [63]: l2[2].append('hello')
- In [64]: l2
- Out[64]: [1, 2, [3, 'SEL', 'hello']]
- In [65]: l3
- Out[65]: [1, 2, [3, 'SEL', 'hello']]
- In [66]:
但是此时我们可以看到, 使用浅拷贝虽然会复制列表里面的内容, 但仅仅是包含第一层, 如果列表里面嵌套了列表, 内层的列表的内容变话的话, 被复制的列表也会变化, 如上所示, 把 l2 的值拷贝给 l3 之后, 修改了 l2 中嵌套的列表, l3 中的也会改变, 如下图所示:
(3) 深拷贝
- In [66]: import copy # 需要导入 copy 模块
- In [67]: l5 = [1, 2, ['a', 'b', ['aa', 'bb'], 3]]
- In [68]: l6 = copy.deepcopy(l5)
- In [69]: l5
- Out[69]: [1, 2, ['a', 'b', ['aa', 'bb'], 3]]
- In [70]: l6
- Out[70]: [1, 2, ['a', 'b', ['aa', 'bb'], 3]]
- In [71]: l5[2][2].append('cc')
- In [72]: l5
- Out[72]: [1, 2, ['a', 'b', ['aa', 'bb', 'cc'], 3]]
- In [73]: l6
- Out[73]: [1, 2, ['a', 'b', ['aa', 'bb'], 3]]
- In [74]:
深度拷贝会完全复制整个列表里的内容, 再次修改之前的列表时, 新列表并不会受影响:
来源: http://www.bubuko.com/infodetail-2821740.html