Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Python: Общие вопросы > функциональное программирование


Автор: sandello 23.5.2008, 11:12
Пытаюсь освоить функциональное программирование на питоне.
Попытался построчно считать файл в список. Час убил, не могу понять как это сделать.

В рамках императивной парадигмы я бы сделал так:
Код

def rl(filename):
  f=open(filename,'r')
  l=f.readline()
  r=[]
  while not l=='':
    r.append(l)
    l=f.readline()
  return r


Как это же изобразить с помощью функционального подхода - ума не приложу.

PS
я знаю про метод f.readlines()  smile

Добавлено @ 11:25

Максимум до чего смог додуматься:
Код

def wb(f,r):
  l=f.readline()
  if l=='':
    return r
  else:
    r.append(l)
    return wb(f,r)


Но хочется обойтись вообще без внутренней переменной.

Автор: Void 23.5.2008, 11:39
Питон не настолько заточен под функциональную парадигму, чтобы это упражнение имело какой-то смысл. К тому же, ввод-вывод подразумевают побочные эффекты, и в Питоне нет никаких средств для их изоляции. Не монады же лепить, в самом деле. Такой код в «грязном» функциональном языке, вроде ML, отличался бы только заменой цикла и append на рекурсивную функцию и cons. В Питоне нет ни оптимизации хвостовой рекурсии, ни эффективных неизменяемых списков, так что и этот вариант является бессмысленным.
Подводя черту: file.readlines — это и есть самый «функциональный» способ решения данной задачи, и не надо придумывать искусственные проблемы.
Прелесть Питона в том, что first class functions, closures, list comprehensions и пр. дополняются возможностями предельно динамического языка. Это не классическое ФП, но по своему не менее выразительный подход.

Автор: sandello 23.5.2008, 12:02
Цель решения данной задачи - научиться. Мне наплевать на оптимизацию рекурсии сейчас smile Задача - парадигму освоить.
В догонку вопрос: какой язык лучше тогда использовать для написания рабочих программ в рамках фунциональной парадигмы?

Автор: Void 23.5.2008, 12:47
Цитата(sandello @  23.5.2008,  14:02 Найти цитируемый пост)
какой язык лучше тогда использовать для написания рабочих программ в рамках фунциональной парадигмы?

Рабочих — это каких? Для какой цели? :-)
Квинтэссенция и передовой край современной функциональщины — это пожалуй всё-таки Haskell.
Достаточно продвинутые теоретически и одновременно приближенные к современном окружению: Scala (JVM) и Nemerle (.NET).
Смешанная парадигма + статическая типизация + приличные компиляторы = ML-оиды (OCaml, SML).
Динамика, параллелизм и отказоустойчивость — Erlang.
Ну и Лисп особняком. У которого функциональная парадигма — тоже одна из.
Остальное, пожалуй, стоит рассматривать только с теоретической точки зрения.

Автор: sandello 23.5.2008, 19:25
Думаю до хаскела или erlang'а тоже доберусь...  После того, как чуть-чуть научусь.
Экспериментировать начал на питоне т.к. немного его знаю smile

Еще вопрос в рамках той же парадигмы. Есть список:
Код

[ ['1',value0],['1',value1],['2',value2] ]

Нужно из него составить словарь
Код

{'1':[value0,value1],'2':[value2]}

Как?

Автор: sandello 23.5.2008, 20:12
Сделал так:
Код

def ff(x,y):
  if x.has_key(y[0]):   
    x[y[0]].append(y[1])
  else:
    x[y[0]]=[y[1]]
  return x
    
result=reduce(ff, incoming_list,{})


Ни как не могу сделать лямбда-функцию, добавляющую новую пару с словарь, в одну строку
что-то вроде
Код

lambda x,y,z:x[y]=z

По уму эта функция должна возвращать x, но как это сделать я пока не понял

Автор: Void 23.5.2008, 20:38
Повторюсь, в Питоне очень туго с недеструктивными операциями, и стандартные типы данных на них никак не заточены. Единственным «функциональным» средством можно считать list comprehensions и generator expression, со всеми вытекающими.
Ну возьмём эту задачу. Если решать императивно, получится вот такое:
Код
s = [['1', value0], ['1', value1], ['2', value2]]
d = {}
for key, value in s:
    d.setdefault(key, []).append(value)

Вариант на генераторах может выглядеть так:
Код
dict((key, [v for k, v in s if k == key]) for key in set(k for k, v in s))

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

В общем, Питон слабо подходит для освоения ФП. Хотя лямбды, функции высшего порядка и т.п. могут произвести впечатление при переходе с языка, где их нет.

Автор: sandello 24.5.2008, 16:59
Мда...
Ну хоть лямбду более-менее освоил с помощью питона и то вперед smile
В Java её нет в явном виде.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)