【问题标题】:Create a dictionary from list of dictionaries selecting specific values从选择特定值的字典列表创建字典
【发布时间】:2022-01-08 00:02:35
【问题描述】:

我有一个字典列表如下,我想创建一个字典来存储列表中的特定数据。

test_list = [
    {
        'id':1,
        'colour':'Red',
        'name':'Apple',
        'edible': True,
        'price':100
    },
    {
        'id':2,
        'colour':'Blue',
        'name':'Blueberry',
        'edible': True,
        'price':200
    },
    {
        'id':3,
        'colour':'Yellow',
        'name':'Crayon',
        'edible': False,
        'price':300
    }
]

例如,一个只存储各种商品的 {id, name, price} 的新字典。

我创建了几个列表:

id_list = []
name_list = []
price_list = []

然后我将我想要的数据添加到每个列表中:

for n in test_list:
   id_list.append(n['id']
   name_list.append(n['name']
   price_list.append(n['price']

但我不知道如何创建字典(或更合适的结构?)以我想要的 {id, name, price} 格式存储数据。感谢帮助!

【问题讨论】:

  • 你考虑过 pandas.DataFrame 吗?
  • 如果您明确显示您想要的格式会有所帮助。
  • csv 标签有何相关性?

标签: python json csv


【解决方案1】:

如果你没有太多数据,你可以使用这个嵌套列表/字典推导:

keys = ['id', 'name', 'price']
result = {k: [x[k] for x in test_list] for k in keys}

这会给你:


{
  'id': [1, 2, 3],
  'name': ['Apple', 'Blueberry', 'Crayon'],
  'price': [100, 200, 300]
}

【讨论】:

  • keys = ['id', 'name', 'price']
  • @MYousefi 说得对
【解决方案2】:

我认为字典列表仍然是正确的数据格式,所以:

test_list = [
    {
        'id':1,
        'colour':'Red',
        'name':'Apple',
        'edible': True,
        'price':100
    },
    {
        'id':2,
        'colour':'Blue',
        'name':'Blueberry',
        'edible': True,
        'price':200
    },
    {
        'id':3,
        'colour':'Yellow',
        'name':'Crayon',
        'edible': False,
        'price':300
    }
]

keys = ['id', 'name', 'price']
limited = [{k: v for k, v in d.items() if k in keys} for d in test_list]

print(limited)

结果:

[{'id': 1, 'name': 'Apple', 'price': 100}, {'id': 2, 'name': 'Blueberry', 'price': 200}, {'id': 3, 'name': 'Crayon', 'price': 300}]

这很好,因为您可以访问它的部分,例如limited[1]['price']

但是,如果您不介意使用第三方库,您的用例非常适合 pandas

import pandas as pd

test_list = [
    {
        'id':1,
        'colour':'Red',
        'name':'Apple',
        'edible': True,
        'price':100
    },
    {
        'id':2,
        'colour':'Blue',
        'name':'Blueberry',
        'edible': True,
        'price':200
    },
    {
        'id':3,
        'colour':'Yellow',
        'name':'Crayon',
        'edible': False,
        'price':300
    }
]

df = pd.DataFrame(test_list)

print(df['price'][1])
print(df)

DataFrame 非常适合这些东西,并且只选择您需要的列:

keys = ['id', 'name', 'price']
df_limited = df[keys]
print(df_limited)

我更喜欢列表字典的原因是,操作列表字典会变得复杂且容易出错,访问单个记录意味着访问三个单独的列表 - 这种方法没有太多优势,除非可能如果您更频繁地访问单个属性,则列表上的某些操作会更快。但在这种情况下,pandas 轻松获胜。

在 cmets 中,您问“假设我有 item_names = ['Apple', 'Teddy', 'Crayon'],我想检查其中一个项目名称是否在 df_limited 变量中,或者我猜是 df_limited['name'] - 有没有办法做到这一点,如果是然后打印说价格,还是操纵价格?”

当然有很多方法,我建议查看一些在线 pandas 教程,因为它是一个非常受欢迎的库,并且在线上有出色的文档和教材。

但是,只是为了说明在这两种情况下检索匹配对象或仅检索它们的价格是多么容易:

item_names = ['Apple', 'Teddy', 'Crayon']

items = [d for d in test_list if d['name'] in item_names]
print(items)
item_prices = [d['price'] for d in test_list if d['name'] in item_names]
print(item_prices)

items = df[df['name'].isin(item_names)]
print(items)
item_prices = df[df['name'].isin(item_names)]['price']
print(item_prices)

结果:

[{'id': 1, 'colour': 'Red', 'name': 'Apple', 'edible': True, 'price': 100}, {'id': 3, 'colour': 'Yellow', 'name': 'Crayon', 'edible': False, 'price': 300}]
[100, 300]

   id    name  price
0   1   Apple    100
2   3  Crayon    300
0    100
2    300

在带有数据框的示例中,有几点需要注意。他们正在使用.isin(),因为使用 in 不会以数据框允许您选择数据df[<some condition on df using df>] 的奇特方式工作,但是pandas 中的所有标准操作都有快速且易于使用的替代方案。更重要的是,您可以在原始的 df 上完成工作 - 它已经拥有您需要的一切。

假设您想将这些产品的价格翻倍:

df.loc[df['name'].isin(item_names), 'price'] *= 2

这使用 .loc 出于技术原因(您不能只修改数据框的任何视图),但在此答案中涉及的内容太多了 - 您将学习查看 pandas。不过,它非常干净和简单,我相信你同意。 (您也可以在前面的示例中使用.loc

在这个简单的示例中,两者都立即运行,但您会发现pandas 对于非常大的数据集表现更好。另外,尝试使用您要求的方法(如已接受的答案中提供的)编写相同的示例,您会发现它并不那么优雅,除非您再次将所有内容压缩在一起:

item_prices = [p for i, n, p in zip(result.values()) if n in item_names]

要得到一个与result 具有相同结构的结果会更加棘手,因为涉及到更多的压缩和解包,或者需要您检查两次列表。

【讨论】:

  • 感谢@Grismar 的回答!这真的很好用,看起来很棒!当我第一次看到它时,会更多地研究熊猫图书馆。假设我有 item_names = ['Apple', 'Teddy', 'Crayon'] 并且我想检查其中一个项目名称是否在 df_limited 变量中,或者我猜是 df_limited['name'] - 有没有办法做到这一点,如果是,然后打印说 @ 987654348@,还是操纵价格?
  • 我为此添加了一些示例 - 但我建议您在询问更多内容之前先查看该库,它有很好的文档记录,并且在线有大量教程,因为它是 Python 最常用的第三方库之一科学和工程。我确实建议尝试使用已接受的答案来做同样的事情 - 看看你喜欢那种场景中的每个解决方案。
猜你喜欢
  • 2019-01-16
  • 1970-01-01
  • 2020-12-14
  • 1970-01-01
  • 2017-05-05
  • 1970-01-01
  • 2018-08-30
  • 2018-11-06
  • 1970-01-01
相关资源
最近更新 更多