поиск во вложенном списке в python - PullRequest
4 голосов
/ 02 ноября 2009

У меня есть список:

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

Я хочу найти komand или sq и получить l[1] возвращено.

Могу ли я как-то определить свою собственную функцию сопоставления для поиска в списке?

Ответы [ 4 ]

11 голосов
/ 02 ноября 2009

Выражение типа:

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

даст вам именно тот подсписок, который вы ищете (или поднимет StopIteration, если такого подсписка нет; если последнее поведение не то, что вы хотите, передайте next второй аргумент [[например, * 1006] * или 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))
1 голос
/ 02 ноября 2009

Вы можете сделать это так:

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 голосов
/ 02 ноября 2009

Да

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']
0 голосов
/ 02 ноября 2009

Если все, что вы пытаетесь сделать, это вернуть первый список, содержащий совпадение для любого из значений, то это будет работать.

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']
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...