Является ли «предварительная проверка» предпочтительным способом избежать добавления типов None или пустых строк при выполнении двойной рекурсии в списках? - PullRequest
0 голосов
/ 22 февраля 2019

Я выполняю некоторые рекурсивные упражнения для списков в python3 и столкнулся с проблемой, при которой мой возвращаемый список был бы заполнен некоторыми необработанными None-типами.

Это конкретное упражнение предназначено для создания функции, котораяудаляет все строки гласных из списка.Все элементы во входном списке являются строками длины один, но список может также содержать больше списков.

def without_vowels(arg):
    vowels = "aeiuoåäöAEIUOÅÄÖ"

    if not arg:
        return arg

    elif isinstance(arg, str):
        if not arg in vowels:
            return arg
        else:
            return ""

    elif isinstance(arg, list):
        if without_vowels(arg[0]) == "":
            return without_vowels(arg[1:])
        else:
            return [without_vowels(arg[0])] + without_vowels(arg[1:])

Ожидаемый результат:

>>> test = ["a", ["h", "e", "j"], ["t", "e", "s", "c", "o"]]
>>> without_vowels(test)
>>> [['h', 'j'], ['t', 's', 'c']]

Первоначально для «удаления»гласные при обнаружении я бы просто ничего не вернул.Это привело к добавлению в список None-типов.

Вывод без обходного пути (строки 10,11, 14-16 удалены):

>>> without_vowels(test)
>>> [None, ['h', None, 'j'], ['t', None, 's', 'c', None]]

Чтобы обойти эту проблему, яизменил код, чтобы он возвращал пустую строку при обнаружении гласных, и добавил «предварительную проверку» перед повторным вызовом функции для продолжения, в основном просто проверяя, найдет ли вызов функции гласную (и возврат «»), и в этом случаеcase перейдите к следующей части аргумента list.

Мне кажется, что я упускаю что-то очевидное, и должно быть лучшее решение без использования обходного пути, подобного этому.

Спасибо

Редактировать: Это конкретное упражнение предназначено для решения с двойной рекурсией, а не с комбинацией итерации и одной рекурсии

Ответы [ 4 ]

0 голосов
/ 22 февраля 2019

Это конкретное упражнение предназначено для решения с двойной рекурсией, а не с комбинацией итерации и единственной рекурсииработа для вас:

VOWELS = set("aeiuoåäöAEIUOÅÄÖ")

def without_vowels(argument):

    if not argument:
        return argument

    head, *tail = argument

    if isinstance(head, list):
        head = without_vowels(head)
    elif head in VOWELS:
        return without_vowels(tail)

    return [head, *without_vowels(tail)]

ИСПОЛЬЗОВАНИЕ

>>> test = ["a", ["h", "e", "j"], ["t", "e", "s", "c", "o"]]
>>> without_vowels(test)
[['h', 'j'], ['t', 's', 'c']]
>>> 
0 голосов
/ 22 февраля 2019

Я пытался сделать это в едином Списке-понимании, но я слишком устал, чтобы заставить его работать.

Вот мое решение вашей проблемы:

def without_vowels(arg):
    vowels = "aeiuoåäöAEIUOÅÄÖ"
    returnList = []
    for entry in arg:
        if type(entry) == str and entry not in vowels:
            returnList.append(entry)
        elif type(entry) == list:
            returnList.append(without_vowels(entry))
    return returnList

test = ["a", ["h", "e", "j"], ["t", "e", "s", "c", "o"]]
print(without_vowels(test))

Ивывод приведенного выше кода:

>>> without_vowels(test)
[['h', 'j'], ['t', 's', 'c']]

Редактировать: я полагаю, что мое решение вернет пустой список, если единственной записью в списке является гласная, но если все в порядке, то это должно сделатьработа.

0 голосов
/ 22 февраля 2019

Я думаю, что следующая реализация делает ваш вопрос спорным:

VOWELS = set("aeiuoåäöAEIUOÅÄÖ")

def without_vowels(arg):
    if isinstance(arg, list):
        return [without_vowels(item) for item in arg if without_vowels(item)]
    elif isinstance(arg, str):
        non_vowels = [ch for ch in arg if ch not in VOWELS]
        if len(non_vowels) > 2:
            return non_vowels
        elif len(non_vowels) == 1:
            return non_vowels[0]
        return non_vowels

test = ["a", ["h", "e", "j"], ["t", "e", "s", "c", "o"]]

print(without_vowels(test))  # -> [['h', 'j'], ['t', 's', 'c']]
0 голосов
/ 22 февраля 2019

Это зависит от того, что вы хотите для «лучшего решения».То, что я считаю простым способом - это удалить гласные из всего, с чем вы сталкиваетесь, повторяя элементы, которые являются последовательностями.Я сделал один шаг с этим:

def without_vowels(arg):
    vowels = "aeiuoåäöAEIUOÅÄÖ"
    if not isinstance(arg, list):
        return arg

    result = [c for c in arg if not isinstance(c, str) or c not in vowels]
    for idx, c in enumerate(result):
        if isinstance(arg, list):
            result[idx] = without_vowels(result[idx])

    return result

test = ["a", ["h", "e", "j"], ["t", "e", "s", "c", "o"]]
print( without_vowels(test) )

Вывод:

[['h', 'j'], ['t', 's', 'c']]

Я не знаю, что он (пока) чище, чем ваш, но он избегает прямой вставки, а затем удаленияпустые элементы.

...