【问题标题】:Checking information in a dataset in Python在 Python 中检查数据集中的信息
【发布时间】:2011-12-12 12:00:02
【问题描述】:

我目前需要使用 Python 2.7 比较包含 MAC 地址的字符串(例如“11:22:33:AA:BB:CC”。目前,我有一个包含 MAC 地址的预配置集和我的脚本遍历集合,将每个新的 MAC 地址与列表中的地址进行比较。这很有效,但随着集合的增长,脚本会大大减慢。只有 100 个左右,您会注意到巨大的差异。

有人对加快这个过程有什么建议吗?将它们存储在一组中是比较的最佳方式,还是将它们存储在 CSV/DB 中更好?

代码示例...

def Detect(p): 
    stamgmtstypes = (0,2,4)
    if p.haslayer(Dot11):
        if p.type == 0 and p.subtype in stamgmtstypes:
            if p.addr2 not in observedclients: 
                # This is the set with location_mutex: 
                detection = p.addr2 + "\t" + str(datetime.now())
                print type(p.addr2)
                print detection, last_location
                observedclients.append(p.addr2) 

【问题讨论】:

  • 道歉 Avasal - 我的意思是“设置” - 原帖已修改。对不起!
  • 您可以将列表转换为集合,这将消除重复..(错误删除原始评论)
  • observedclients 应该是一组吗?好吧,从您展示的内容来看,这是一个列表,而不是一组。 Sets 没有.append 方法。您使用.add 添加到集合。
  • observedclients 确实是集合(或者我相信)。我在代码的开头将其声明为“observedclients = []”。这可能是我的问题所在?我现在假设我应该将我的集合声明为“observed = []”,然后声明为“observedclients = set(observed)”?
  • 好吧,[] 创建了一个列表。您需要set() 来创建一个。然后你用observedclients.add(p.addr2) 添加它。它可能会提高性能。

标签: python performance list iteration scapy


【解决方案1】:

该帖子提到“脚本遍历集合,将每个新的 MAC 地址与列表中的地址进行比较。”

要充分利用集合,请不要遍历它们进行逐一比较。而是使用集合操作,如 union()intersection()difference()

s = set(list_of_strings_containing_mac_addresses)
t = set(preconfigured_set_of_mac_addresses)
print s - t, 'addresses in the list but not preconfigured'

【讨论】:

    【解决方案2】:

    尝试使用set。声明集合使用set(),而不是[](因为后者声明了一个空的list)。

    list 中的查找具有O(n) 的复杂性。当列表增长时,这就是你的情况(复杂性随着n 的增长而增长O(n))。

    平均而言,set 中的查找复杂度为 O(1)

    http://wiki.python.org/moin/TimeComplexity

    此外,您还需要更改部分代码。 set 中没有 append 方法,因此您需要使用 observedclients.add(address) 之类的方法。

    【讨论】:

    • ovgolovin,道歉 - 我原来的帖子有错误。我的意思是“设置”而不是“列表”。我已经在使用集合而不是列表,但仍然遇到同样的问题。
    • @thefragileomen 很奇怪,因为如果集合的大小变大了,应该不会增加算法的难度(因为复杂度是O(1),它与@987654336的大小无关@)。
    【解决方案3】:

    首先,您需要profile your code 了解瓶颈的确切位置...

    另外,作为一般建议,考虑 psyco,虽然 there are a few times when psyco doesn't help

    一旦发现瓶颈,cython 可能会有用,但您需要确保在 cython 源中声明所有变量。

    【讨论】:

    • 谢谢迈克。我假设瓶颈只是 MAC 地址列表的大小。如前所述,它只适用于少数 MAC 地址,但随着列表大小的增长,这是脚本变慢的时候。我想我要牢记一条规则——永远不要做出假设!
    • @thefragileomen,你的剧本有多长?
    • Mike,它只有大约 100 行长,有 5 个函数。我认为导致问题的函数只有几行,但它确实有一些嵌套的 if 函数。我已经编辑了我的主要问题,其中包含
    • @thefragileomen,看起来你使用的是scapy,对吧? scapy 是纯 python,因此变得非常慢...一些其他的数据包吊挂库(例如pcs)为您卸载与cython 一起工作...所以这可能 在你的情况下提供帮助......我不能肯定
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-02-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-06
    • 1970-01-01
    相关资源
    最近更新 更多