ПОСЛЕДНИЕ Постижения: Ссылки на компоненты - PullRequest
8 голосов
/ 20 февраля 2011

В итоге: мне нужно написать «Понимание списка», в котором я ссылаюсь на список, который создается «Постижением списка».

Это может быть не то, что вам нужно делать каждый день, но я неНе думаю, что это тоже необычно.

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

В любом случае, я не могу написать этот конкретный список.Причина: выражение, которое мне нужно написать, имеет такую ​​форму:

[ some_function(s) for s in raw_data if s not in this_list ]

В этом псевдокоде «this_list» относится к списку, созданному путем оценки этого списка.И именно поэтому я застрял - потому что this_list не создается до тех пор, пока мое понимание списка не будет оценено, и потому что этот список еще не создан к тому времени, когда мне нужно обратиться к нему, я не знаю, как обратиться кэто.

То, что я рассмотрел до сих пор (и что может быть основано на одном или нескольких ложных предположениях, хотя я точно не знаю, где):

  • нене должен ли интерпретатор python дать этому строящемуся списку имя?я так думаю

  • что временное имя, вероятно, взято из какого-то связанного метода, использованного для создания моего списка ('сумма'?)

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

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

Ответы [ 4 ]

3 голосов
/ 20 февраля 2011

Раньше был способ сделать это, используя недокументированный факт, что во время построения списка его значение хранилось в локальной переменной с именем _[1].__self__.Однако это перестало работать в Python 2.7 (возможно, раньше, я не обращал пристального внимания).

Вы можете делать то, что хотите, в понимании единого списка, если вы сначала настроили внешнюю структуру данных.Поскольку весь ваш псевдокод, по-видимому, работал с this_list, он проверял его на предмет наличия в нем каждого s - то есть теста членства - я изменил его на set с именем seen какоптимизация (проверка на членство в list может быть очень медленной, если список большой).Вот что я имею в виду:

raw_data = [c for c in 'abcdaebfc']

seen = set()
def some_function(s):
    seen.add(s)
    return s

print [ some_function(s) for s in raw_data if s not in seen ]
# ['a', 'b', 'c', 'd', 'e', 'f']

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

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

def some_function(s):
    # do something with or to 's'...
    return s

def add_unique(function, data):
    result = []
    seen = set(result) # init to empty set
    for s in data:
        if s not in seen:
            t = function(s)
            result.append(t)
            seen.add(t)
    return result

print add_unique(some_function, raw_data)
# ['a', 'b', 'c', 'd', 'e', 'f']

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

2 голосов
/ 20 февраля 2011

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

Обратите внимание, что даже если вы можете ссылаться на "список вконструкция ", ваш подход все равно потерпит неудачу, потому что s в любом случае отсутствует в списке - результат some_function(s) равен.

2 голосов
/ 20 февраля 2011

Насколько я знаю, нет никакого способа получить доступ к пониманию списка, поскольку он создается.

Как упоминалось в KennyTM (и если порядок записей не имеет значения), тогда вы можете использоватьset вместо.Если вы работаете на Python 2.7 / 3.1 и выше, вы даже получите заданное понимание:

{ some_function(s) for s in raw_data }

В противном случае цикл for тоже не так уж и плох (хотя он будет ужасно масштабироваться)

l = []
for s in raw_data:
    item = somefunction(s)
    if item not in l:
        l.append(item)
0 голосов
/ 20 февраля 2011

Почему бы вам просто не сделать: [ some_function(s) for s in set(raw_data) ]

Это должно сделать то, что вы просите. За исключением случаев, когда вам нужно сохранить порядок предыдущего списка.

...