【问题标题】:Filtering a list of lists of a tuple with regex使用正则表达式过滤元组列表
【发布时间】:2014-02-20 19:36:55
【问题描述】:

查看底部附近的编辑

我只是在学习 python。我正在尝试过滤元组列表,以仅保留包含与正则表达式匹配的元组的列表。

基本上我有:

start_list=[[(blah1,123)],[(xblah2,123)],[(somethingelse1,123)],[(wookie1,123)]]

我想对元组索引 0 中包含“blah”的任何内容进行正则表达式过滤。
预期结果:

result_list=[[(blah1,123)],[(xblah2,123)]]

到目前为止我所拥有的:

import re
result_list=[[tup for tup in sub_list if re.search('.*blah.*',tup[0])] for sub_list in start_list]

但是我不断收到正则表达式错误

  File "/usr/lib/python2.7/re.py", line 137, in match
    return _compile(pattern, flags).match(string)
TypeError: expected string or buffer

最重要的是,我担心这会返回与正则表达式不匹配的元组的空白列表。任何帮助表示赞赏,谢谢!

编辑:好的,我尝试更简单地提出问题导致我犯了印刷错误等。我道歉。我正在使用 pysnmp getbulk,我只想获得与基本 oid 匹配的结果。这是我打印元组列表时得到的结果:

[[(ObjectName(1.3.6.1.2.1.4.24.7.1.7.1.4.172.16.0.100.32.2.0.16777724.1.4.172.16.0.89), Integer(16777724))], [(ObjectName(1.3.6.1.2.1.4.24.7.1.7.1.4.172.16.0.100.32.2.0.16777724.1.4.172.16.0.90), Integer(16777724))], [(ObjectName(1.3.6.1.2.1.4.24.7.1.7.1.4.172.16.0.160.27.2.0.16778357.0.0), Integer(16778357))], [(ObjectName(1.3.6.1.2.1.4.24.7.1.7.1.4.172.16.0.192.29.2.0.16778348.0.0), Integer(16778348))]]

我刚刚意识到这个 ObjectName 不是一个字符串,所以我想我不能在它上面使用正则表达式。但我确实想过滤具有与以下基本 oid 匹配的 ObjectName 的元组:

1.3.6.1.2.1.4.24.7.1.7.1.4.172.16.0.100.32

我需要用谷歌搜索一下这个 ObjectName 现在是什么...

【问题讨论】:

  • start_list 在我看来不像元组列表。最后两个元素根本不包含任何元组。
  • @Kevin 这正是他的问题。他的列表包含不是元组列表的元素,他想取消它。
  • 我认为我们阅读问题的方式不同。我听到“此列表仅包含元组列表,我想保留与此正则表达式匹配的列表”,您听到“除其他内容外,此列表还包含元组列表,我想保留那些是与此正则表达式匹配的元组列表"
  • 无论如何,当我运行这段代码时,我得到NameError: name 'blah1' is not defined。 OP,请提供一个 SSCCE 来证明你的问题。
  • 为什么您发布了调用re.match() 的代码的部分回溯,但在这里向我们展示了使用re.search() 的代码?

标签: python regex tuples list-comprehension


【解决方案1】:

除了最后两个列表不包含元组这一事实外,您还必须以另一种方式执行 for 循环。

[tup for sublist in start_list for tup in sublist]

【讨论】:

    【解决方案2】:

    正则表达式只能用于字符串。你应该把你的元组写成 ("xblah2",123)。

    【讨论】:

      【解决方案3】:

      假设 (string,int) 元组的列表:

      start_list = [("blah1",123),("xblah2",123),("somethingelse1",123),("wookie1",123)]
      

      您可以使用in 代替正则表达式进行检查。

      result_list = [t for t in start_list if "blah" in t[0]]
      

      【讨论】:

        【解决方案4】:

        首先,在作为嵌套列表推导的result_list 中,外部列表推导返回sub_list。所以内部列表理解应该在这方面工作。

        此外,您收到预期字符串或缓冲区错误的确切原因是因为您的blah1xblah2somethinglese1 等都不是字符串。假设它们是字符串并修复我们的列表理解:

        result_list = [[tup for tup in sub_list if re.search('.*blah.*',sub_list[0][0])] for sub_list in start_list]
        

        这将导致您提到的空列表。

        [[('blah1', 123)], [('xblah2', 123)], [], []]
        

        要解决这个问题,您可以过滤上述列表理解为空列表

        result_list = filter(lambda x: x, [[tup for tup in sub_list if re.search('.*blah.*',sub_list[0][0])] for sub_list in start_list])
        

        注意,lambda x: xlambda x: len(x)>0 相同

        【讨论】:

        • 谢谢,你是对的,它们不是字符串,所以我仍然需要弄清楚。我将使用您的 lambda 技巧来过滤空列表。
        【解决方案5】:

        感谢 @warunsl 的 lambda 片段从我的列表中删除空列表。在评论者指出元组不包含字符串后,我最终弄清楚了。我使用 str() 将元组中的对象转换为字符串并在其上运行正则表达式。我最终得到的是:

        result_list = filter(lambda x: x, [[tup for tup in sub_list if re.match('1.3.6.1.2.1.4.24.7.1.7.1.4.172.16.0.100.32', str(tup[0]))] for sub_list in start_list])
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2016-03-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-10-20
          • 1970-01-01
          • 2020-09-12
          相关资源
          最近更新 更多