社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

玩转python字典与列表(下)

dwzb • 7 年前 • 592 次点击  

玩转python字典与列表(下)

本文首发于知乎

本文分为如下部分

  • 列表转置
  • 字典转置
  • 字典列表之间的转换
  • 总结

列表转置

已有

l = [['a', 'b', 'c'],
     [1, 2, 3]]

想得到

[('a', 1), ('b', 2), ('c', 3)]

代码如下

[z for z in zip(*l)]

zip函数在list的转置中充当重要作用,它的基础用法是这样的

for z in zip(['a', 'b', 'c'], [1, 2, 3]):
    print(z)

# 输出
('a', 1)
('b', 2)
('c', 3)

字典的转置

已有

m = {'Bob': {'age': 30, 'country': 'America'},
     'Mary': {'age': 20, 'country': 'China'},
     'Frank': {'age': 25, 'country': 'America'}}

想得到

{'age': {'Bob': 30, 'Frank': 25, 'Mary': 20},
 'country': {'Bob': 'America', 'Frank': 'America', 'Mary': 'China'}}

如果借用pandas直接转置即可

>>> m = {'Bob': {'age': 30, 'country': 'America'},
...      'Mary': {'age': 20, 'country': 'China'},
...      'Frank': {'age': 25, 'country': 'America'}}
>>>
>>> import pandas as pd
>>> pd.DataFrame(m)
             Bob    Frank   Mary
age           30       25     20
country  America  America  China
>>> pd.DataFrame(m).transpose()
      age  country
Bob    30  America
Frank  25  America
Mary   20    China
>>> pd.DataFrame(m).transpose().to_dict()
{'age': {'Mary': 20, 'Bob': 30, 'Frank': 25}, 'country': {'Mary': 'China', 'Bob': 'America', 'Frank': 'America'}}

如果我们单独使用字典的知识也是可以办到的

from collections import defaultdict
result = defaultdict(dict)
for names, infos in m.items():
    for k, v in infos.items():
        result[k].update({names: v})
        
dict(result)

字典列表之间的转换

已有

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

想要得到

[('a', 1), ('b', 2), ('c', 3)]

[{'name': 'a', 'num': 1}, 
 {'name': 'b', 'num': 2},
 {'name': 'c', 'num': 3}]

两种形式

代码如下

# 第一个
[z for z in zip(*d.values())]

# 第二个
[dict(zip(d.keys(), z)) for


    
 z in zip(*d.values())]
# 或
[dict(zip(d, z)) for z in zip(*d.values())]

总结

首先来看一下我们遇到了哪些形式的数据

{'name' : ['a', 'b', 'c'],
 'num' : [1, 2, 3]}
 
{'Bob': {'age': 30, 'country': 'America'},
 'Mary': {'age': 20, 'country': 'China'},
 'Frank': {'age': 25, 'country': 'America'}}
 
{'age': {'Bob': 30, 'Frank': 25, 'Mary': 20},
 'country': {'Bob': 'America', 'Frank': 'America', 'Mary': 'China'}}
 
[('a', 1), ('b', 2), ('c', 3)]
[{'a', 1}, {'b', 2}, {'c', 3}]
[{'a': 1}, {'b': 2}, {'c': 3}]
[{'name': 'Bob', 'age': 30, 'country': 'America'},
 {'name': 'Mary', 'age': 20, 'country': 'China'},
 {'name': 'Frank', 'age': 25, 'country': 'America'}]

下面总结一下看待字典列表的思想

  • 首先,最重要的是列表这种结构,将集合、元组都看做列表(无序等都是细枝末节)
  • 而字典可以看做特殊的列表,即对每个元素都命名了的列表,键是名,值相当于列表的元素

读者可以试着使用这种思想去看上面这些数据,就会明白,为什么某些数据直接可以用pd.DataFrame转化为数据框,他们都相当于二维列表形成的矩阵。一个维度,如果以列表形式呈现则视为行,如果以字典形式呈现则视为列。

这些数据的相互转化中,只要根据要生成结果的形式,记住几个套路即可:

1.如果结果是一个字典,简单的用字典生成式等方式不谈。当值是动态更新的时候,则使用collections模块中的defaultdict设置值的类型,使用循环填入数据,如果值类型是list则用append方法填入,如果是dict则用update方法填入。

注:有时结果是字典会直接人为指定键,值用列表生成式等直接获得,这是一种比较不通用的做法,因为需要人为指定键的话,就无法将其改装为一个适合各种情况的函数了。

2.如果结果是一个列表,则用列表生成式,构造每一个元素的形式即可

3.如果涉及到了转置问题,其实本质上都是列表的转置,往zip函数那里想,有时也可以用defaultdict

欢迎关注我的知乎专栏

专栏主页:python编程

专栏目录:目录

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


今天看啥 - 高品质阅读平台
本文地址:http://www.jintiankansha.me/t/vDGx7GKtOP
Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/12678
 
592 次点击