【问题标题】:working with lists and dictionaries in python在 python 中使用列表和字典
【发布时间】:2023-02-25 08:52:49
【问题描述】:

我确定我应该能够找到这个,但我已经看过了,但我似乎无法确定如何处理我正在寻找的一些用户案例。我想搜索字典列表,然后拉回一个子集或计算一个值出现的频率。

例如,从下面的列表中,我希望能够说

返回键“AP”中包含“WAP1”的所有字典的列表或返回键“network”=“net1”的列表数

所以根据逻辑搜索词返回一个新列表,其中仅包含前 2 个字典项和数字“3”

我用过,wap = next((item for item in ls_dict if item['AP']=='WAP1'),'none') 但这只会得到第一个项目。我也不确定为什么如果不使用“下一步”就不能工作并抛出这个错误。 <0x7f9146cba0 处的生成器对象>

在一天结束的时候,我希望能够在一个大列表中搜索一个 mac 地址的出现,或者拉出一个我可以用于未来操作的所有字典对象的列表,或者简单地计算它们出现的次数出现。

预先感谢您提供任何指导,我知道这一定很简单,但一直在寻找一段时间,但无法弄清楚。

> ls_dict = [{'network': 'NET1', 'AP': 'WAP1', 'MAC': 'FF01', 'ap_mac' : 'eeeeeeeeeeee'},
           {'network': 'NET1', 'AP': 'WAP1', 'MAC': 'FF02', 'ap_mac' : 'eeeeeeeeeeee'},
           {'network': 'NET1', 'AP': 'WAP2', 'MAC': 'FF03', 'ap_mac' : 'eeeeeeeeeeee'},
           {'network': 'NET2', 'AP': 'WAP3', 'MAC': 'FF04', 'ap_mac' : 'eeeeeeeeeeee'}]

【问题讨论】:

  • 你知道列表理解,或者使用filter函数吗?
  • 我没有,但自从阅读了你的评论后,我开始自学它们,这看起来是我正在寻找的东西,谢谢。

标签: python dictionary


【解决方案1】:

如果列表很大,您可能希望使用pandas 来处理数据帧。您始终可以使用 to_dict 导出(列表)词典:

import pandas as pd

ls_dict = [{'network': 'NET1', 'AP': 'WAP1', 'MAC': 'FF01', 'ap_mac' : 'eeeeeeeeeeee'},
           {'network': 'NET1', 'AP': 'WAP1', 'MAC': 'FF02', 'ap_mac' : 'eeeeeeeeeeee'},
           {'network': 'NET1', 'AP': 'WAP2', 'MAC': 'FF03', 'ap_mac' : 'eeeeeeeeeeee'},
           {'network': 'NET2', 'AP': 'WAP3', 'MAC': 'FF04', 'ap_mac' : 'eeeeeeeeeeee'}]

df = pd.DataFrame(ls_dict)
df[df['AP']=="WAP1"].to_dict(orient='record'))

输出:

[{'network': 'NET1', 'AP': 'WAP1', 'MAC': 'FF01', 'ap_mac': 'eeeeeeeeeeee'},
{'network': 'NET1', 'AP': 'WAP1', 'MAC': 'FF02', 'ap_mac': 'eeeeeeeeeeee'}]

或者:

len(df[df['network']=="NET1"]) # returns 3

【讨论】:

  • 谢谢,我会查一下,有些列表可能超过 10,000,这看起来是一个简洁高效的解决方案,感谢您的输入。 apricate 你花时间去教育。
【解决方案2】:

大熊猫的回答是完全没问题,但海报和你们都对效率提出了要求。如果您从字典列表开始,从性能的角度来看,pandas 没有帮助。

让我们根据您的示例创建一些更大的数据:

import random

APs= [f"WAP{i}" for i in range(1, 9)]
ls_dict = [
    {'network': 'NET1', 'AP': random.choice(APs), 'MAC': 'FF01', 'ap_mac' : 'eeeeeeeeeeee'}
    for _ in range(10_000)
]

现在我们可以验证的一些测试方法返回相同的结果:

import pandas as pd

def t1(ls_dict):
    df = pd.DataFrame(ls_dict)
    return df[df['AP']=="WAP1"].to_dict(orient='records')

def t2(ls_dict):
    return [r for r in ls_dict if r["AP"] == "WAP1"]

print(t1(ls_dict) == t2(ls_dict))

这将(应该)导致True

所以撇开内存不谈,让我们看看这些使用timeit的表现如何:

setup = """
import pandas as pd
import random

APs= [f"WAP{i}" for i in range(1, 9)]
ls_dict = [
    {'network': 'NET1', 'AP': random.choice(APs), 'MAC': 'FF01', 'ap_mac' : 'eeeeeeeeeeee'}
    for _ in range(10_000)
]

ls_dict = [
    {'network': 'NET1', 'AP': 'WAP1', 'MAC': 'FF01', 'ap_mac' : 'eeeeeeeeeeee'},
    {'network': 'NET1', 'AP': 'WAP1', 'MAC': 'FF02', 'ap_mac' : 'eeeeeeeeeeee'},
    {'network': 'NET1', 'AP': 'WAP2', 'MAC': 'FF03', 'ap_mac' : 'eeeeeeeeeeee'},
    {'network': 'NET2', 'AP': 'WAP3', 'MAC': 'FF04', 'ap_mac' : 'eeeeeeeeeeee'}
] * 5_000

def t1(ls_dict):
    df = pd.DataFrame(ls_dict)
    return df[df['AP']=="WAP1"].to_dict(orient='records')

def t2(ls_dict):
    return [r for r in ls_dict if r["AP"] == "WAP1"]
"""

print(f'pandas dataframe: {timeit.timeit("t1(ls_dict)", setup=setup, number=100)}')
print(f'comprehension   : {timeit.timeit("t2(ls_dict)", setup=setup, number=100)}')

在我的系统上,结果是:

pandas dataframe: 3.5198207999928854
comprehension   : 0.08080889997654594

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-25
    • 1970-01-01
    • 2021-04-09
    • 2018-02-06
    相关资源
    最近更新 更多