Как отказаться от середины списка, используя списки? - PullRequest
0 голосов
/ 10 сентября 2009

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

for x in firstList:
    firstFunc(x)
    secondFunc(x)
    x = process(x)
    if x.discard == True:
        (get rid of x)
secondList.append(firstList)

Ответы [ 6 ]

2 голосов
/ 10 сентября 2009

Просто мысль, и она мало что делает для документации, но почему бы не попробовать:

def masterFunc(x):
    firstFunc(x)
    secondFunc(x)
    process(x)
    return x.discard

secondList = [ x for x in firstList if masterFunc(x) ]

Хорошие новости: делает то, что вы просили, строго говоря. Плохие новости: он скрывает firstFunc, secondFunc и процесс

Похоже, у вас уже есть проблемы с побочными эффектами и разделением команд / запросов в примере, поэтому я думаю, что этот хак не так благороден, как небольшая очистка кода. Вы можете обнаружить, что некоторые методы нуждаются в инвертировании (x.firstFunc () вместо firstFunc (x)), а другие - в разбивке. Может даже быть более хороший способ, чем x.discard, иметь дело с фильтрацией.

1 голос
/ 10 сентября 2009

Знаете, ваше лучшее решение - просто инициализировать secondList, как вам нравится, и выполнять все три функции в обычном цикле, поскольку все они зависимы и содержат логику, которая не просто фильтрует (вы говорите, что процесс устанавливает атрибуты. .. Я предполагаю, что вы имеете в виду, кроме отбросить):

# If secondList not initialized...
secondList = []
for x in firstList:
    firstFunc(x)
    secondFunc(x)
    process(x)
    if not x.discard:
        secondList.append(x)

Понятия списков здесь не сильно помогают, так как вы выполняете обработку каждой функции (хотя они отнимают одну или две строки; зависит от того, что вы ищете в «чистом» коде). Если бы весь процесс () возвращал значение «Истина», если элемент должен быть в новом списке, и значение «Ложь», если элемент не должен быть в новом списке, то приведенное ниже будет действительно лучше, ИМО.


Если firstFunc (x) и secondFunc (x) действительно изменяют результат x.discard после process (), а результат process (x) равен просто x, я бы сделал следующее в вашей ситуации:

for x in firstList:
    firstFunc(x)
    secondFunc(x)
secondList = [ x for x in firstList if not process(x).discard ]

Если результат процесса (x) отличается от x, хотя, как показывает ваш пример, вы можете также изменить эту последнюю строку на следующую:

interimList = [ process(x) for x in firstList ]
secondList = [ x for x in interimList if not x.discard ]

Обратите внимание, что если вы хотите добавить эти результаты в secondList, используйте secondList.extend ([...]).

Редактировать: я понял, что я ошибочно написал "do not " change, но я имел в виду, если они действительно изменяют результат process ().

Редактировать 2: Описание / код очистки.

0 голосов
/ 10 сентября 2009

Запишите это в виде двух списочных представлений: одно собирает данные, которые могут нуждаться в фильтрации, а другое выполняет фильтрацию. Сделайте так, чтобы firstFunc и secondFunc возвращали x (как это делает процесс), а затем вы можете написать это так:

unfilteredList = [secondFunc(firstFunc(x)) for x in firstList]
secondList = [x for x in unfilteredList if not x.discard]
0 голосов
/ 10 сентября 2009

звучит как

def allProcessing(x)
  firstFunc(x)
  secondFunc(x)
  return !(process(x).discard)

newList = filter(allProcessing, oldList)
0 голосов
/ 10 сентября 2009

несколько вещей:

  • вы не можете append список, вам нужно использовать extend.
  • не нужно == True бит, используйте только if x.discard:
  • вы бы предпочли создать новый список со значениями, которые вы не хотите отбрасывать, и не загрязняете цикл удалением.

чтобы у вас было что-то вроде:

tmp = []
for x in first_list:
    x = process(x)
    if not x.discard:
        tmp.append(x)
second_list.extend(tmp)

понимание списка, очевидно, было бы более питонным:

[i for i in first_list if not process(i).discard]
0 голосов
/ 10 сентября 2009

Редактировать: процесс (x) необходим для x.discard, что означает, что ответ:

Нет, нет более чистого пути. И то, как ты это делаешь, уже чисто.

Старый ответ:

Не совсем, нет. Вы можете сделать это:

def process_item(x):
    firstFunc(x)
    secondFunc(x)
    x = process(x)

def test_item(x):
    return x.discard == False

list = [process_item(x) for x in firstList if test_item(x)]

Но это не чище, и также требуется, чтобы x.discard был установлен до того, как вы его обработаете, что, похоже, не из вашего кода.

Понимание списка не "чище". Это более короткие способы написания простой обработки списков. Обработка вашего списка включает в себя три этапа. Это не совсем "просто". :)

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