【发布时间】:2010-12-12 02:59:43
【问题描述】:
我有一个清单:
l = [['en', 60, 'command'],['sq', 34, 'komand']]
我想搜索komand 或sq 并返回l[1]。
我可以为列表搜索定义自己的匹配函数吗?
【问题讨论】:
我有一个清单:
l = [['en', 60, 'command'],['sq', 34, 'komand']]
我想搜索komand 或sq 并返回l[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))
【讨论】:
(<genexpr>).next() ;-) (+1)
next 成为内置函数,它现在是一个重要且非常有用的习语。
你可以这样做:
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'])
【讨论】:
如果您要做的只是返回包含任何值匹配的第一个列表,那么这将起作用。
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']
【讨论】:
是的:
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)) 也可以。