Введение в язык Питон


Связывание выражений - часть 2


      firsts1 = [car x | x <- list_of_list] where car (x:xs) = x

      -- 'let' clause for expression-level binding

      firsts2 = let car (x:xs) = x in [car x | x <- list_of_list]

      -- more idiomatic higher-order 'map' technique

      firsts3 = map car list_of_list where car (x:xs) = x

      -- Result: firsts1 == firsts2 == firsts3 == [1,4,7]

Грэг Эвинг (Greg Ewing) заметил, что мы можем достичь того же эффекта, воспользовавшись списочными встраиваниями Python  (list comprehensions); мы даже можем сделать это почти столь же ясным способом, как в Haskell:

    #------ Python 2.0+ expression-level name bindings ------#

          >>> list_of_list = [[1,2,3],[4,5,6],[7,8,9]]

          >>> [car_x for x in list_of_list for car_x in (x[0],)]

          [1, 4, 7]

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

     #------- Python block-level bindings with 'map()' -------#

          >>> list_of_list = [[1,2,3],[4,5,6],[7,8,9]]

          >>> let = Bindings()

          >>> let.car = lambda l: l[0]

          >>> map(let.car,list_of_list)

          [1, 4, 7]

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