Промежуточная переменная в понимании списка для одновременной фильтрации и преобразования

У меня есть список векторов (в Python), которые я хочу нормализовать, и в то же время удаляя векторы, которые изначально имели небольшие нормы.

Список входных данных, например,

a = [(1,1),(1,2),(2,2),(3,4)] 

И мне нужен вывод (x * n, y * n) с n = (x * 2 + y * 2) ** – 0.5

Если бы мне просто нужны были нормы, например, это было бы легко с пониманием списка:

 an = [ (x**2+y**2)**0.5 for x,y in a ] 

Было бы также легко хранить только нормализованное значение х, например, но я хочу, чтобы эта временная переменная «n» использовалась в двух вычислениях и выбрасывала ее.

Я не могу просто использовать функцию лямбда слишком, потому что мне также нужно n, чтобы отфильтровать список. Итак, каков наилучший способ?

Прямо сейчас я использую это вложенное понимание списка здесь (с выражением во внутреннем списке):

 a = [(1,1),(1,2),(2,2),(3,4)] [(x*n,y*n) for (n,x,y) in (( (x**2.+y**2.)**-0.5 ,x,y) for x,y in a) if n < 0.4] # Out[14]: # [(0.70710678118654757, 0.70710678118654757), # (0.60000000000000009, 0.80000000000000004)] 

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

3 Solutions collect form web for “Промежуточная переменная в понимании списка для одновременной фильтрации и преобразования”

 Is this really the best way? 

Ну, это работает эффективно, и если вы действительно хотите писать oneliners, тогда это лучшее, что вы можете сделать.

С другой стороны, простая 4-строчная функция будет делать то же самое яснее:

 def normfilter(vecs, min_norm): for x,y in vecs: n = (x**2.+y**2.)**-0.5 if min_norm < n: yield (x*n,y*n) normalized = list(normfilter(vectors, 0.4)) 

Btw, есть ошибка в вашем коде или описании – вы говорите, что вы отфильтровываете короткие векторы, но ваш код делает наоборот: p

Это говорит о том, что использование форлупа может быть самым быстрым способом. Обязательно проверьте результаты timeit на своем собственном компьютере, так как эти результаты могут варьироваться в зависимости от ряда факторов (аппаратное обеспечение, ОС, версия Python, длина a т. Д.).

 a = [(1,1),(1,2),(2,2),(3,4)] def two_lcs(a): an = [ ((x**2+y**2)**0.5, x,y) for x,y in a ] an = [ (x*n,y*n) for n,x,y in an if n < 0.4 ] return an def using_forloop(a): result=[] for x,y in a: n=(x**2+y**2)**0.5 if n<0.4: result.append((x*n,y*n)) return result def using_lc(a): return [(x*n,y*n) for (n,x,y) in (( (x**2.+y**2.)**-0.5 ,x,y) for x,y in a) if n < 0.4] 

дает следующие результаты:

 % python -mtimeit -s'import test' 'test.using_forloop(test.a)' 100000 loops, best of 3: 3.29 usec per loop % python -mtimeit -s'import test' 'test.two_lcs(test.a)' 100000 loops, best of 3: 4.52 usec per loop % python -mtimeit -s'import test' 'test.using_lc(test.a)' 100000 loops, best of 3: 6.97 usec per loop 

Кража кода из unutbu, вот более крупный тест, включая версию numpy и версию итератора. Обратите внимание, что преобразование списка в numpy может стоить некоторое время.

 import numpy # a = [(1,1),(1,2),(2,2),(3,4)] a=[] for k in range(1,10): for j in range(1,10): a.append( (float(k),float(j)) ) npa = numpy.array(a) def two_lcs(a): an = [ ((x**2+y**2)**-0.5, x,y) for x,y in a ] an = [ (x*n,y*n) for n,x,y in an if n < 5.0 ] return an def using_iterator(a): def normfilter(vecs, min_norm): for x,y in vecs: n = (x**2.+y**2.)**-0.5 if n < min_norm: yield (x*n,y*n) return list(normfilter(a, 5.0)) def using_forloop(a): result=[] for x,y in a: n=(x**2+y**2)**-0.5 if n<5.0: result.append((x*n,y*n)) return result def using_lc(a): return [(x*n,y*n) for (n,x,y) in (( (x**2.+y**2.)**-0.5 ,x,y) for x,y in a) if n < 5.0] def using_numpy(npa): n = (npa[:,0]**2+npa[:,1]**2)**-0.5 where = n<5.0 npa = npa[where] n = n[where] npa[:,0]=npa[:,0]*n npa[:,1]=npa[:,1]*n return( npa ) 

и результат …

 nlw@pathfinder:~$ python -mtimeit -s'import test' 'test.two_lcs(test.a)' 10000 loops, best of 3: 65.8 usec per loop nlw@pathfinder:~$ python -mtimeit -s'import test' 'test.using_lc(test.a)' 10000 loops, best of 3: 65.6 usec per loop nlw@pathfinder:~$ python -mtimeit -s'import test' 'test.using_forloop(test.a)' 10000 loops, best of 3: 64.1 usec per loop nlw@pathfinder:~$ python -mtimeit -s'import test' 'test.using_iterator(test.a)' 10000 loops, best of 3: 59.6 usec per loop nlw@pathfinder:~$ python -mtimeit -s'import test' 'test.using_numpy(test.npa)' 10000 loops, best of 3: 48.7 usec per loop 
  • возможно ли распознавание списка Python с доступом к индексу / перечислением?
  • Python обертывается вокруг списка, когда индекс списка выходит за пределы диапазона
  • Python - Синтаксическая ошибка в двоеточии в списке
  • Расширенный срез, который начинается с начала последовательности с отрицательным шагом
  • Как читать текстовый файл в список или массив с помощью Python
  • Самый быстрый способ подсчета числа вхождений в списке Python
  • Как инициализировать словарь пустых списков в Python?
  • Получить список значений из списка словарей в python
  •  
    Interesting Posts for Van-Lav

    Расчет собственных значений Python выполняется намного медленнее, чем вычисления MATLAB на моем компьютере. Зачем?

    python не принимает аргументы ключевых слов

    сортировать csv по столбцу

    sqlalchemy: TypeError: создающий экземпляр типа uncashable, sqlalchemy

    Как удалить теги из строки в python с помощью регулярных выражений? (НЕ в HTML)

    как перенаправить на конкретный URL-адрес на 404

    TableView to PDF (несколько страниц)

    Django динамически получает URL-адрес просмотра и проверяет, является ли его текущая страница

    SOAP 1.2 клиент python

    Изменение внешнего вида панели прокрутки в tkinter (с использованием стилей ttk)

    Msgstr "устаревший ассоциативный прокси, родительский объект вышел из сферы действия" с помощью Flask-SQLAlchemy

    Количество способов разбиения числа на Python

    nump / scipy аналог mminsearch Matlab

    Нити Python: блокировка внутри оператора while

    Показатели Matplotlib не работают после диалога с файлом Tkinter

    Python - лучший язык программирования в мире.