Fórum Root.cz
Hlavní témata => Vývoj => Téma založeno: RecursiveFarts 17. 08. 2018, 01:47:51
-
Jde nějak napsat v Pythonu a C++ rekurzivní anonymní funkce? Mám například [1, 2, 3, 4, 5].fmap(fact) pro faktoriál, ale místo zvlášť definované funkce fact chci mít jako argument fmapu jen lambda výraz. V podstatě něco jako Recall v R, ale to zjevně Python nemá a C++ už vůbec ne.
-
fact = lambda x: C
nebo
def fun(x):
return 1 if x == 0 else x * fact(x-1)
map(fun, [1, 2, 3, 4])
-
Ten první způsob se neuložil celý, zde je kompletní
fact = lambda x: 1 if x == 0 else x * fact(x-1)
-
A ten druhý je taky blbě, nyní správně
def fact(x):
return 1 if x == 0 else x * fact(x-1)
map(fact, [1, 2, 3, 4])
-
A ten druhý je taky blbě, nyní správně
def fact(x):
return 1 if x == 0 else x * fact(x-1)
map(fact, [1, 2, 3, 4])
To není anonymní, otázka zněla, jak dát ten lambda výraz přímo do volání mapu jako parametr.
-
Mozne to je, ale nevim, zda tohle zrovna v Pythonu chces delat
https://stackoverflow.com/questions/481692/can-a-lambda-function-call-itself-recursively-in-python
-
Mozne to je, ale nevim, zda tohle zrovna v Pythonu chces delat
https://stackoverflow.com/questions/481692/can-a-lambda-function-call-itself-recursively-in-python
To Y jde taky udělat jako callable. V tom C++ jako funktor (ve dvou ze tři smyslů tohoto slova).
-
A ten druhý je taky blbě, nyní správně
def fact(x):
return 1 if x == 0 else x * fact(x-1)
map(fact, [1, 2, 3, 4])
To není anonymní, otázka zněla, jak dát ten lambda výraz přímo do volání mapu jako parametr.
To je zvěrstvo, nepythonické :-) Lambdy nepoužívat. V Pythonu by se mělo programovat pythonicky, to hlavní výhoda Pythonu, vlastní odlišná filosofie, a ne erovsky. Navíc rekurzi raději obcházet.
-
A ten druhý je taky blbě, nyní správně
def fact(x):
return 1 if x == 0 else x * fact(x-1)
map(fact, [1, 2, 3, 4])
To není anonymní, otázka zněla, jak dát ten lambda výraz přímo do volání mapu jako parametr.
To je zvěrstvo, nepythonické :-) Lambdy nepoužívat. V Pythonu by se mělo programovat pythonicky, to hlavní výhoda Pythonu, vlastní odlišná filosofie, a ne erovsky. Navíc rekurzi raději obcházet.
To je otázka na samodružný bod funkce vyššího řádu. V dynamickém jazyce to je vskutku zvěrstvo. Ale v tom C++ to už smysl má. Co je “erovsky”?
-
... a C++ už vůbec ne.
Ale dá se.
constexpr auto fact = [](unsigned int i) {
constexpr auto recursive = [](unsigned int i, auto &self) -> unsigned int {
return i ? i * self(i - 1, self) : 1;
};
return recursive(i, recursive);
};
static_assert(fact(3) == 6);
static_assert(fact(4) == 24);
-
Co je “erovsky”?
IMHO myslí způsob programování typický pro jazyk R
-
... a C++ už vůbec ne.
Ale dá se.
constexpr auto fact = [](unsigned int i) {
constexpr auto recursive = [](unsigned int i, auto &self) -> unsigned int {
return i ? i * self(i - 1, self) : 1;
};
return recursive(i, recursive);
};
static_assert(fact(3) == 6);
static_assert(fact(4) == 24);
Ano, dá se, ale jinak, tohle není anonymní. Jak to bude bez použití “recursive”?
-
... a C++ už vůbec ne.
Ale dá se.
constexpr auto fact = [](unsigned int i) {
constexpr auto recursive = [](unsigned int i, auto &self) -> unsigned int {
return i ? i * self(i - 1, self) : 1;
};
return recursive(i, recursive);
};
static_assert(fact(3) == 6);
static_assert(fact(4) == 24);
Ano, dá se, ale jinak, tohle není anonymní. Jak to bude bez použití “recursive”?
Dobře, tak anonymně a bez použití recursive ;D.
static_assert([](unsigned int i) {
constexpr auto not_recursive = [](unsigned int i, auto &self) -> unsigned int {
return i ? i * self(i - 1, self) : 1;
};
return not_recursive(i, not_recursive);
}(3) == 6);
-
... a C++ už vůbec ne.
Ale dá se.
constexpr auto fact = [](unsigned int i) {
constexpr auto recursive = [](unsigned int i, auto &self) -> unsigned int {
return i ? i * self(i - 1, self) : 1;
};
return recursive(i, recursive);
};
static_assert(fact(3) == 6);
static_assert(fact(4) == 24);
Ano, dá se, ale jinak, tohle není anonymní. Jak to bude bez použití “recursive”?
Dobře, tak anonymně a bez použití recursive ;D.
static_assert([](unsigned int i) {
constexpr auto not_recursive = [](unsigned int i, auto &self) -> unsigned int {
return i ? i * self(i - 1, self) : 1;
};
return not_recursive(i, not_recursive);
}(3) == 6);
Furt blbě.
-
Furt blbě.
Je lepší psát k tématu, a ne jak se cítíš ;D.
-
Je lepší psát k tématu
Tak to dělej, někdo chce anonymní funkci a ty píšeš kód mimo mísu.
-
Je lepší psát k tématu
Tak to dělej, někdo chce anonymní funkci a ty píšeš kód mimo mísu.
Vždyť je anonymní. To spíš mimo mísu jsi ty ;).
-
možná tohle http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0200r0.html ?
-
Je lepší psát k tématu
Tak to dělej, někdo chce anonymní funkci a ty píšeš kód mimo mísu.
Vždyť je anonymní. To spíš mimo mísu jsi ty ;).
Není. Máš ta pojmenovanou lokální proměnnou. Až se jí zbavíš, tak to bude řešením. Ale vzhledem k tomu, žes ani nebyl schopen pochopit zadání, těžko přijdeš s řešením.
-
Je lepší psát k tématu
Tak to dělej, někdo chce anonymní funkci a ty píšeš kód mimo mísu.
Vždyť je anonymní. To spíš mimo mísu jsi ty ;).
Není. Máš ta pojmenovanou lokální proměnnou. Až se jí zbavíš, tak to bude řešením. Ale vzhledem k tomu, žes ani nebyl schopen pochopit zadání, těžko přijdeš s řešením.
Ty ses dobrej mamlas, clovece, poposkoc si... ;)
-
Není. Máš ta pojmenovanou lokální proměnnou. Až se jí zbavíš, tak to bude řešením. Ale vzhledem k tomu, žes ani nebyl schopen pochopit zadání, těžko přijdeš s řešením.
Tak bez pojmenování lokálních proměnných, nebo dokonce parametrů, jsem to ještě nezkoušel. Snad na tuto úroveň jednou dospěju ;D.
-
možná tohle http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0200r0.html ?
Podle mě je to v zásadě to samé. Do auto paramteru lambdy se předává požadovaná funkce. V tomto případě objekt třídy y_combinator_result, který zavolá uloženou funkci.
-
možná tohle http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0200r0.html ?
Podle mě je to v zásadě to samé. Do auto paramteru lambdy se předává požadovaná funkce. V tomto případě objekt třídy y_combinator_result, který zavolá uloženou funkci.
almost_gcd se tam použije jenom jednou, to bych řekl, že je docela rozdíl
-
clojure style rekurze v pythonu jde
import types, inspect
def recur(*args, **kwargs):
return types.FunctionType(inspect.stack()[1][0].f_code, globals())(*args, **kwargs)
fact = lambda x: x * recur(x - 1) if x > 1 else x
v praxi to použije jen dement.
-
clojure style rekurze v pythonu jde
import types, inspect
def recur(*args, **kwargs):
return types.FunctionType(inspect.stack()[1][0].f_code, globals())(*args, **kwargs)
fact = lambda x: x * recur(x - 1) if x > 1 else x
v praxi to použije jen dement.
To bezpochyby, protože to je dementní řešení. Žes to sem dal, hanba by tě měla fackovat. (P.S. Proč tu není zvracející smajlík?)
-
možná tohle http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0200r0.html ?
Podle mě je to v zásadě to samé. Do auto paramteru lambdy se předává požadovaná funkce. V tomto případě objekt třídy y_combinator_result, který zavolá uloženou funkci.
almost_gcd se tam použije jenom jednou, to bych řekl, že je docela rozdíl
Tak protože to předávání funkce se dějě v operátoru volání objektu y_combinator_result.
template<class ...Args>
decltype(auto) operator()(Args &&...args) {
return fun_(std::ref(*this), std::forward<Args>(args)...);
}
Auto parametr gcd v lambdě je pak reference na objekt y_combinator_result. Výhoda je, že si to předávání nemusíš psát sám, ale udělá to ten objekt y_combinator_result.
-
Mozne to je, ale nevim, zda tohle zrovna v Pythonu chces delat
https://stackoverflow.com/questions/481692/can-a-lambda-function-call-itself-recursively-in-python
je to dost nepekne
Python 2.7.6 (default, Nov 23 2017, 15:49:48)
[GCC 4.8.4] on linux2
Type "copyright", "credits" or "license()" for more information.
>>> map(lambda n: (lambda f, *a: f(f, *a))(lambda rec, n: 1 if n == 0 else n*rec(rec, n-1), n), [1, 2, 3, 4, 5])
[1, 2, 6, 24, 120]
>>>
[code python 3.4]
Python 3.4.3 (default, Nov 28 2017, 16:41:13)
[GCC 4.8.4] on linux
Type "copyright", "credits" or "license()" for more information.
>>> map(lambda n: (lambda f, *a: f(f, *a))(lambda rec, n: 1 if n == 0 else n*rec(rec, n-1), n), [1, 2, 3, 4, 5])
<map object at 0x7f3c31f384a8>
>>> list(map(lambda n: (lambda f, *a: f(f, *a))(lambda rec, n: 1 if n == 0 else n*rec(rec, n-1), n), [1, 2, 3, 4, 5]))
[1, 2, 6, 24, 120]
>>>
[/code]
-
To bezpochyby, protože to je dementní řešení. Žes to sem dal, hanba by tě měla fackovat. (P.S. Proč tu není zvracející smajlík?)
Na dementní otázku dementní řešení. Zatím jsem neviděl lepší.
-
To bezpochyby, protože to je dementní řešení. Žes to sem dal, hanba by tě měla fackovat. (P.S. Proč tu není zvracející smajlík?)
Na dementní otázku dementní řešení. Zatím jsem neviděl lepší.
Ty jsi ale kretén. Ta otázka je normální a zajímavá, akorát že ty vůbec nevíš, která bije. Vrať se do zvláštní školy.
-
Ty jsi ale kretén. Ta otázka je normální a zajímavá, akorát že ty vůbec nevíš, která bije. Vrať se do zvláštní školy.
recall z R v Pythonu, přesně jak tazatel chtěl
import types, inspect
def recall(*args, **kwargs):
return types.FunctionType(inspect.stack()[1][0].f_code, globals())(*args, **kwargs)
list(map(lambda x: x * recall(x - 1) if x > 1 else x, [1, 2, 3, 4, 5]))
# [1, 2, 6, 24, 120]