阅读 390

玩转python字典与列表(上)

本文首发于知乎

我们来看下面6组数据

d = {'name' : ['a', 'b', 'c'],
    'num' : [1, 2, 3]}
lt = [('a', 1), ('b', 2), ('c', 3)]
ld = [{'name': 'a', 'num': 1}, 
      {'name': 'b', 'num': 2},
      {'name': 'c', 'num': 3}]

ld1 = [{'a': 1}, {'b': 2}, {'c': 3}]
ls = [{'a', 1}, {'b', 2}, {'c', 3}]
d1 = {'a': 1, 'b': 2, 'c': 3}
复制代码

考虑一下他们都表示什么,他们之间的关系是什么,有没有发蒙?

下面我们就好好理一下这些基础的数据类型

1.从data.frame的角度考虑

从data.frame的角度考虑,前面三个的内在含义是一样的,它们都可以直接调用pandas库中的DataFrame函数构造一个数据框,如下所示

>>> d = {'name' : ['a', 'b', 'c'],
...     'num' : [1, 2, 3]}
>>> lt = [('a', 1), ('b', 2), ('c', 3)]
>>> ld = [{'name': 'a', 'num': 1},
...       {'name': 'b', 'num': 2},
...       {'name': 'c', 'num': 3}]
>>>
>>> import pandas as pd
>>> pd.DataFrame(d)
  name  num
0    a    1
1    b    2
2    c    3
>>> pd.DataFrame(lt, columns=('name', 'num'))
  name  num
0    a    1
1    b    2
2    c    3
>>> pd.DataFrame(ld)
  name  num
0    a    1
1    b    2
2    c    3
复制代码

d是按照列拆分,lt是按照行拆分,ld也是按行拆分,只是每次都带有索引项。

我们用爬虫抓取到的数据最常见的是ld的形式,如下图所示

(改进 json)

ld向其他两种类型转化的代码如下所示

>>> ld
[{'name': 'a', 'num': 1}, {'name': 'b', 'num': 2}, {'name': 'c', 'num': 3}]
>>> [tuple(i.values()) for i in ld]
[('a', 1), ('b', 2), ('c', 3)]
>>> {'name': [d['name'] for d in ld],
...  'num': [d['num'] for d in ld]}
{'name': ['a', 'b', 'c'], 'num': [1, 2, 3]}
复制代码

两两相互转化也是可以实现的,思路类似,这里不再赘述

2.字典融合

来看下面这两个之间的关系

ld1 = [{'a': 1}, {'b': 2}, {'c': 3}]
d1 = {'a': 1, 'b': 2, 'c': 3}
复制代码

一个字典内本身就可以有多个键值对,所以说以字典为元素的列表,是可以融合成为一个字典的

>>> ld1 = [{'a': 1}, {'b': 2}, {'c': 3}]
>>> result = {}
>>> for d in ld1:
...     result.update(d)
...
>>> result
{'c': 3, 'a': 1, 'b': 2}

# 第二种方法
>>> {k:v for d in ld1 for k,v in d.items()}
{'c': 3, 'a': 1, 'b': 2}
复制代码

一个字典当然也可以拆分成多个小字典的列表

>>> d1 = {'a': 1, 'b': 2, 'c': 3}
>>> [{k:v} for k,v in d1.items()]
[{'c': 3}, {'a': 1}, {'b': 2}]
复制代码

3.字典的转化

这次我们来看这三个

d1 = {'a': 1, 'b': 2, 'c': 3}
lt = [('a', 1), ('b', 2), ('c', 3)]
ls = [{'a', 1}, {'b', 2}, {'c', 3}]
复制代码

后两个可以直接用dict转化为字典,但是有些差异

>>> lt = [('a', 1), ('b', 2), ('c', 3)]
>>> dict(lt)
{'c': 3, 'a': 1, 'b': 2}

>>> ls = [{'a', 1}, {'b', 2}, {'c', 3}]
>>> dict(ls)
{1: 'a', 2: 'b', 'c': 3}
复制代码

因为ls是以集合为元素的列表,集合是无序,因此转化为字典时,谁作为键谁作为值就不一定了。

d1反过来也是可以转化为lt ls

>>> d1 = {'a': 1, 'b': 2, 'c': 3}
>>> [tuple(i) for i in d1.items()]
[('c', 3), ('a', 1), ('b', 2)]
>>> [(k, v) for k, v in d1.items()] # 第二种方法
[('c', 3), ('a', 1), ('b', 2)]

>>> [{k, v} for k, v in d1.items()]
[{'c', 3}, {1, 'a'}, {2, 'b'}]
复制代码

4.三个列表

接下来看下面三个的对比

lt = [('a', 1), ('b', 2), ('c', 3)]
ls = [{'a', 1}, {'b', 2}, {'c', 3}]
ld1 = [{'a': 1}, {'b': 2}, {'c': 3}]
复制代码

这三个都是列表,只是列表的元素分别为元组、集合、字典,它们之间的相互转化关系也是非常明确的,举几个例子

>>> lt = [('a', 1), ('b', 2), ('c', 3)]
>>> ls = [{'a', 1}, {'b', 2}, {'c', 3}]
>>> ld1 = [{'a': 1}, {'b': 2}, {'c': 3}]
>>> [{k, v} for k, v in lt] # lt 到 ls
[{1, 'a'}, {2, 'b'}, {'c', 3}] 
>>> [{k: v} for k, v in lt] # lt 到 ld1
[{'a': 1}, {'b': 2}, {'c': 3}]
>>> [(k, v) for d in ld1 for k, v in d.items()] # ld1 到 lt
[('a', 1), ('b', 2), ('c', 3)]

>>> [(k, v) for k, v in ls]
[(1, 'a'), (2, 'b'), ('c', 3)]
>>> [{k: v} for k, v in ls]
[{1: 'a'}, {2: 'b'}, {'c': 3}]
复制代码

可以看到ls无法很好地转化为其他两个,因为集合内部元素是无序的。

就对比到这里了,如果有小伙伴想到更有趣的嵌套方式,欢迎在评论区留言!

欢迎关注我的知乎专栏

专栏主页:python编程

专栏目录:目录

版本说明:软件及包版本说明

文章分类
后端