Python数据类型:列表和字典

这里将列表和字典统一整理,是因为这两者有很多相似之处。这是两种最常见、而且功能最强大的集合体类型。

列表


  1. 任意对象的有序集合
  • 偏移量读取
  • 可变长度、异构以及任意嵌套
  • 可变序列分类
  • 属于对象引用的数组
    • 列表内的项,并不是拷贝,而是对象的引用,和字典一样。
  • 列表操作:
操作 解释
L = [] 空列表
L = [0,1] 常量
L = ['wk', ['wk']] 嵌套
L = list('wang') 可迭代
L = list(range(-4, 2))
L[i] 索引
L[i][j] 二维索引
L[i:j] 切片
len(L) 长度
L1 + L2 合并
L * 2 重复
for x in L: print(x) 迭代
2 in L 成员
L.append(4) 追加、插入、排序、搜索等
L.extend([5, 6])
L.insert(index, X)
L.index(1)
L.Count(X)
L.sort()
L.reverse()
del L[k] 删除等操作
del L[i:j]
L.pop()
L.remove(2)
L[i:j] = []
L[i] = 1
L[i:j] = [4, 5, 6, 7]
L = [x**2 for x in range(5)] 列表解析
list(map(ord, 'spam')) map对列表’spam’作ord应用
  • 列表是可变的

可变的意思是列表可以在原处直接修改,修改列表内元素。由于列表内存储的是对象的引用,所以修改以后影响的也是对象的引用。

  • 支持原处修改,修改操作:索引和切片

索引赋值:L[index] = ''

切片赋值:L[i:j] = []

切片赋值分两步理解:

  1. 删除。首先删除左边列表中切片内容;
  2. 插入。右侧列表内容插入列表L。

同时,切片赋值也可以看成列表的切片删除:

L[i:j] = []

既是先删除左侧切片,再赋值右侧。右侧是空列表,所以插入空。

由切片赋值的代码可以引出一个问题:

思考:L[2:5] = L[3:6] 两个切片有重合,是否可行。

可行,右侧的值在左侧被删除以前就被取出来了。

  • 列表方法:method

方法:method是附属于特定对象的函数,实际上是引用函数的属性。对象的一个属性。

方法提供了特定类型的工具,针对特定类型。


排序sort

原地对列表进行排序。

sort使用 python 标准的比较检验 做默认值(默认字符串比较),所以可以使用key指定不同的("name=value")配置选项比较内容。

比如:

1
2
L.sort(key=str.lower)
L.sort(key=str.lower, reverse=True)

warning:appendsort原处修改列表对象,并不返回列表(实际上两者的返回值是None)。
所以使用appendsort时,不应该再赋值。

同时,排序可以作为内置函数使用了,可以排序任何集合不仅仅是列表,并返回一个列表:

1
2
sorted(L, key=str.lower, reverse=True)
sorted([x.lower() for x in L], reverse=True)

逆序reversed

逆序内置函数reversed需要包装在一个列表内:
list(reversed(L))

字典


  1. 使用键来读取
  2. 任意对象的无序集合
  3. 可变长、异构、任意嵌套
  4. 属于可变映射类型
  5. 对象引用表
    • 和列表一样
  • 字典操作
操作 解释
D = {} 空字典
D = {'spam':2, 'm':1} 常量
D = {'coffee':{'milk':1, 'water':0}} 嵌套
D = dict.fromkeys(['wk', 'ok']) 特殊构造函数
D = dict(zip(keyslist, valueslist))
D = dict(name='wk', age=18)
D['name'] 索引
D['name']['firstname'] 嵌套索引
'name' in D 成员
D.keys() 键视图
D.values() 视图对象:值
D.items() 键+值,元组形式
D.copy() 副本
D.get(key, default) 对key默认赋值
D.update(otherD) 合并
D.pop(key) 删除
len(D) 长度
D[key] = 1 修改、赋值
del D[key] 删除
list(D.keys()) 键视图
D1.keys() & D2.keys() 集合操作
D = {x: x*2 for x in range(10)} 字典解析

创建字典的方式:

  1. 可以事先拼出整个字典的时候使用

    {'name' : 'wk', 'age' : '18'}

  2. 需要动态的建立字典的时候使用

    1
    2
    3
    d = {}
    d['name'] = 'wk'
    d['age'] = 18
  3. 需求代码少,可要求键是字符串才行

    d(name = 'wk', age=18)

  4. 键值在运行时逐步建立序列

    d([('name', 'wk'), ('age', 18)])

  5. zip一起使用

    1
    2
    3
    key_list = ['name', 'age']
    value_list = ['wk', 18]
    d(zip(key_list, value_list))

tips


  • 对字典进行迭代操作
1
2
for x in D:
print(x)

其实隐含的是

1
2
for x in D.keys():
print(x)

这里,D.keys()python2和3的表现不同,只是都可以作为迭代器。

  • 用数字做key,可以使用字典模拟列表的表现。
  • 避免missing-key错误

判断字典key是否存在的时候,经常遇到missing-key错误。
避免missing-key错误的三种方式:

  1. if测试

    1
    2
    3
    4
    if key in D:
    print(D[key])
    else:
    print(0)
  2. try except

    1
    2
    3
    4
    try:
    print(D[key])
    except KeyError:
    print(0)
  3. get默认值

    D.get(key, 0)

python 3中的字典


  1. 支持进阶字典解析表达式
  2. .keys \ .values \ .items,返回可迭代的视图,需要用list()
  3. 不再支持相对大小的比较,支持手动比较
  4. 没有.has_key(),使用in成员测试:key in dict
  • 字典解析

    于是,字典解析表达式:

    {k : v for (k, v) in zip(key_list, value_list)}

默认所有键的值相等的时候:dict.fromkeys(key_list, 0)

  • 字典视图

    字典的项视图可以和集合混合进行集合操作,除了.values()

    这时候,字典视作键视图。

  • 字典键排序

    由于.keys()是视图对象,所以想排序需要list(.keys())

    也可以使用sorted(.keys()), sorted(dict)

  • 字典比较

    比较排序后的键:sorted(.items()) < sorted(.items())

  • 字典hsa_keyin

    判断字典成员,in代替has_key