Условно входя в цикл for - PullRequest
       0

Условно входя в цикл for

0 голосов
/ 28 сентября 2018

Как избежать повторения кода в цикле, если аргумент представляет собой последовательность (список, кортеж) или пропустить цикл, но выполнить действие только один раз?

def foo(arg1,sequence=None):
    # If possible, loop, else do it once
        if isinstance(sequence,(list,tuple)):
            for value in sequence:
                do_something(arg1)
        else:
            do_something(arg1)

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

РЕДАКТИРОВАТЬ: Вопрос не является дубликатом Как в Pythonопределить, является ли объект итеративным? , как предлагается.Я не хочу вводить другое условие.Я хочу избежать повторения.

Ответы [ 4 ]

0 голосов
/ 28 сентября 2018

С точки зрения разработки программного обеспечения , было бы интересно разделить это на две функции:

  1. функция, которая делает что-то итеративное в случае, если это не список иликортеж (или что-то еще), например, упаковав его в список или кортеж;и
  2. функция, которая выполняет итерацию по элементам после того, как мы делаем ее итеративной, и выполняет обработку, например:
def make_iterable(iterable):
    if not isinstance(iteable, (list,tuple)):
        return (iterable, )
    return iterable

def foo(arg1 ,sequence=None):
    for item in <b>make_iterable(</b>sequence<b>)</b>:
        do_something(arg1, item)

Так что теперь мы можем легко сделать больше вещей итеративными.Например, мы можем вернуть пустой кортеж для None, так что None разрешен как способ избежать любой итерации:

def make_iterable(iterable):
    if <b>iterable is None</b>:
        return ()
    if not isinstance(iteable, (list,tuple)):
        return (iterable, )
    return iterable

Также легко повторно использовать описанный выше метод во всех видах методов, которые позволяют вводить как один объект, так и повторяемый.

Обратите внимание, что могут быть некоторые проблемы с вышеупомянутымНекоторые типы являются итеративными, но сами по себе не являются элементами, для которых вы хотите выполнить итерацию: например, str ing является итеративным (вы можете выполнять итерацию по его символам).В этом случае В Python, как мне определить, является ли объект итеративным? будет успешным, но может быть плохой идеей «распаковать» строку.Но вы, возможно, не захотите перебирать строку, когда вы называете ее foo(4, 'foobar'), а видите ее как отдельный элемент.

0 голосов
/ 28 сентября 2018

Единственный другой разумный способ, который я могу придумать, - преобразовать все в последовательность и затем безоговорочно выполнить итерацию.Это относительно часто встречается в коде Python, и его часто извлекают во вспомогательную функцию.

if not isinstance(sequence, (list, tuple)):
    sequence = [sequence]
for value in sequence:
    ...
0 голосов
/ 28 сентября 2018

Обычный способ Python - «просить прощения вместо разрешения».То есть попробуйте считать его итеративным, и , если это не удастся , предположите, что это не

try:
    for value in sequence:
         do_something(arg1)
except TypeError:
    do_something(arg1)

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

0 голосов
/ 28 сентября 2018

Стандартизируйте цикл, являющийся регистром по умолчанию, и преобразуйте ваш отдельный регистр в итеративный:

if not isinstance(sequence, (list, tuple)):
    sequence = [sequence]

for value in sequence:
    do_something(value)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...