【问题标题】:searching within nested list in python在python的嵌套列表中搜索
【发布时间】:2010-12-12 02:59:43
【问题描述】:

我有一个清单:

l = [['en', 60, 'command'],['sq', 34, 'komand']]

我想搜索komandsq 并返回l[1]

我可以为列表搜索定义自己的匹配函数吗?

【问题讨论】:

    标签: python list nested search


    【解决方案1】:

    这样的表达式:

    next(subl for subl in l if 'sq' in subl)
    

    将为您提供您正在搜索的子列表(如果没有这样的子列表,则提高 StopIteration;如果后一种行为不是您想要的,则传递 next 第二个参数 [[例如,@987654324 @ 或 None,这取决于你到底想要什么!]] 在这种情况下返回)。因此,只需使用此结果值,或将其分配给您想要的任何名称,等等。

    当然,你可以轻松地将这个表达式装扮成你喜欢的任何类型的函数,例如:

    def gimmethesublist(thelist, anitem, adef=None):
        return next((subl for subl in thelist if anitem in subl), adef)
    

    但如果您正在处理特定的变量或值,则通常最好使用内联表达式编码。

    编辑:如果您想搜索多个项目以找到包含任何一个(或更多)项目的子列表,

    its = set(['blah', 'bluh'])
    next(subl for subl in l if its.intersection(subl))
    

    如果您想找到包含所有您的项目的子列表,

    next(subl for subl in l if its.issubset(subl))
    

    【讨论】:

    • 等等,什么?从来没想过这样用next,不知道是奇怪还是真的好用!在 Python 2.5 中,这是(<genexpr>).next() ;-) (+1)
    • @kaizer,在 2.5 版本中它不太有用,因为它让您无法控制“没有满足条件”的情况(因此您通常必须添加一个 try/except StopIteration 这需要很多优雅远去)。在 2.6 及更高版本中,由于 next 成为内置函数,它现在是一个重要且非常有用的习语。
    • 如何调整这种技术以返回搜索词的索引?或者您是否必须依靠循环方法?
    【解决方案2】:

    你可以这样做:

    def find(value, seq):
        for index, item in enumerate(seq):
            if value in item: 
                return index, item
    
    In [10]: find('sq', [['en', 60, 'command'],['sq', 34, 'komand']])
    Out[10]: (1, ['sq', 34, 'komand'])
    

    或者如果你想要一个通用的解决方案:

    def find(fun, seq):
        for index, item in enumerate(seq):
            if fun(item): 
                return index, item
    
    def contain(value):
        return lambda l: value in l
    
    In [14]: find(contain('komand'), [['en', 60, 'command'],['sq', 34, 'komand']])
    Out[14]: (1, ['sq', 34, 'komand'])
    

    【讨论】:

      【解决方案3】:

      如果您要做的只是返回包含任何值匹配的第一个列表,那么这将起作用。

      def search(inlist, matches):
          for li in inlist:
              for m in matches:
                  if m in li:
                      return li
          return None
      
      >>> l = [['en', 60, 'command'],['sq', 34, 'komand']]
      >>> search(l, ('sq', 'komand'))
      ['sq', 34, 'komand']
      

      【讨论】:

        【解决方案4】:

        是的:

        has_oneof = lambda *patterns: lambda: values any(p in values for p in patterns)
        result = itertools.ifilter(has_oneof('komand', 'sq'), l).next()
        print result # prints ['sq', 34, 'komand']
        

        【讨论】:

        • result = (x for x in l if has_oneof('komand', 'sq')(x)) 也可以。
        • 第一行冒号错位。
        猜你喜欢
        • 2013-11-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-03-06
        • 2018-10-15
        • 1970-01-01
        • 2011-10-16
        相关资源
        最近更新 更多