在Python中搜索嵌套列表

4

我有一个列表:

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

我希望搜索komandsq并返回l[1]

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

4个回答

11

像这样的表达式:

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

如果存在该子列表,next函数将返回你正在寻找的子列表(或引发StopIteration异常)。如果后一种行为不是你想要的,可以向next传递第二个参数(例如[]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) - u0b34a0f6ae
@kaizer,在2.5版本中,它不太有用,因为它无法控制“没有满足条件”的情况(所以通常需要添加try/except StopIteration,这会削弱很多优雅之处)。在2.6及更高版本中,由于next成为内置函数,它现在是一个重要且非常有用的习惯用法。 - Alex Martelli
2
这种技术如何适应返回搜索词的索引?或者你是否需要退回到循环的方法? - T3db0t

1
你可以这样做:
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'])

0
如果你只想返回包含任何一个值的第一个列表,那么这个代码就可以用。
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']

0

是的:

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)) 也可以工作。 - Omnifarious
第一行冒号放错位置了。 - Craig McQueen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接