Как указать индекс конкретных элементов в каждом подсписке вложенного списка? - PullRequest
6 голосов
/ 03 ноября 2019

У меня есть несколько вложенных списков, которые являются перестановками друг друга в подсписках:

x = [
['a', [['b', 'c', [['e', 'd']]]]],
['a', [['b', [['e', 'd']], 'c']]],
[[['b', 'c', [['e', 'd']]]], 'a'],
['a', [[[['d', 'e']], 'c', 'b']]], 
['a', [['b', [['d', 'e']], 'c']]]
]

Я хочу выбрать только те, которые соответствуют этому требованию: если подсписки содержат элемент 'd' или 'b 'в нем, он должен иметь индекс 0 в этом подсписке. Таким образом, среди списков в x должен быть выбран только

['a', [['b', [['d', 'e']], 'c']]]

, потому что 'd' имеет индекс 0 в своем подсписке и в то же время 'b' имеет индекс 0 в своем подсписке. Я попробовал эту функцию:

def limitation(root, nested):
    result = []
    for i in nested:
        if isinstance(i, list):
            return limitation(root, i)
        else:
            if (i in ['d', 'b']  and nested.index(i) == 0):
                return root
for i in x:
    print(limitation(i, i))

Но вывод был такой:

['a', [['b', 'c', [['e', 'd']]]]]
['a', [['b', [['e', 'd']], 'c']]]
[[['b', 'c', [['e', 'd']]]], 'a']
['a', [[[['d', 'e']], 'c', 'b']]]
['a', [['b', [['d', 'e']], 'c']]]

Так что он не учел, что и 'd', и 'b' должны иметь индекс 0 тамподсписки. Не могли бы вы помочь мне исправить это?

Ответы [ 4 ]

2 голосов
/ 03 ноября 2019

Если sub-list содержит 'b' or 'd', этот элемент должен быть в первом индексе [0]:

x = [
['a', [['b', 'c', [['e', 'd']]]]],
['a', [['b', [['e', 'd']], 'c']]],
[[['b', 'c', [['e', 'd']]]], 'a'],
['a', [[[['d', 'e']], 'c', 'b']]],
['a', [['b', [['d', 'e']], 'c']]]
]


def limitation(nested):
    for index, subelement in enumerate(nested):
        if isinstance(subelement, list):
            if not limitation(subelement):
                return False
        else:
            if subelement in ['d', 'b'] and not index:
                return False
    return True


for element in x:
    if limitation(element):
        print(element)  # ['a', [['b', [['d', 'e']], 'c']]]
1 голос
/ 03 ноября 2019

Вы можете сделать это следующим образом:

x = [
['a', [['b', 'c', [['e', 'd']]]]],
['a', [['b', [['e', 'd']], 'c']]],
[[['b', 'c', [['e', 'd']]]], 'a'],
['a', [[[['d', 'e']], 'c', 'b']]], 
['a', [['b', [['d', 'e']], 'c']]]
]

def is_valid(sub, seen=0):
    if sub[0] in ('b', 'd'):
        if seen == 1:
            # we found 'b' and 'd' at the right positions
            return True
        else:
            # we found the first one of them
            seen = 1

    elif any(item in sub for item in ('b', 'd')):
        # this sublist has 'b' or 'd' in other than first position
        return False

    # still undecided, we check the sublists recursively
    for item in sub:
        if isinstance(item, list):
            return is_valid(item, seen)

[s for s in x if is_valid(s)]
# [['a', [['b', [['d', 'e']], 'c']]]]
0 голосов
/ 03 ноября 2019

Вы можете использовать простую рекурсию:

def is_valid(d):
  return all(is_valid(a) if isinstance(a, list) else (a not in {'b', 'd'} or not i) for i, a in enumerate(d))


x = [['a', [['b', 'c', [['e', 'd']]]]], ['a', [['b', [['e', 'd']], 'c']]],[[['b', 'c', [['e', 'd']]]], 'a'], ['a', [[[['d', 'e']], 'c', 'b']]], ['a', [['b', [['d', 'e']], 'c']]]]
result = [i for i in x if is_valid(i)]

Вывод:

[
 ['a', [['b', [['d', 'e']], 'c']]]
]
0 голосов
/ 03 ноября 2019

Проблема в том, что вы перестаете искать больше списков в тех списках, которые вы нашли либо в «b», либо в «d». Например, вызовите функцию как:

limitation(x[0], x[0])

Сначала она проверит, есть ли 'a' в ['a', [['b', 'c', [['e', 'd']]]]] - это список -> это не список, поэтому он продолжает проверять, является ли это' b 'или' d '-> это не так, поэтому цикл переходит к следующему элементу. Теперь он проверит, является ли [['b', 'c', [['e', 'd']]]] списком -> так оно и есть, поэтому он снова вызывает функцию с помощью ['b', 'c', [[' e ',' d ']]]. Теперь он проверит, является ли 'b' списком -> это не так, поэтому теперь он проверяет, является ли он 'b' или 'd' - каким он является, и поэтому возвращается корень. Он никогда не приступает к проверке оставшихся списков, включая, в данном случае, тот, который содержит «d» не в нулевой позиции. Надеюсь, это имеет смысл.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...