Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
fn/fns — function/functions; сокращения такого вида часто используют в расчетных программах (типа x/xs/xss, y/ys). Также, как i/j/k для счетчика цикла, вполне понятно и предсказуемо.a, x — accumulator, x. В том же руби часто используют e в качестве element, a/acc для аккумулятора. Более-менее говорящее имя переменной. Как регистр ax/eax/rax =)В том же руби часто используют e в качестве element, a/acc для аккумулятора.def func(arg):
return arg*arg
map(func, [2,3])
>>> [4, 9]
people = [{'имя': 'Маша', 'рост': 160},
{' рост ': 'Саша', ' рост ': 80},
{'name': 'Паша'}]
heights = map(lambda x: x['рост'],
filter(lambda x: 'рост' in x, people))
if len(heights) > 0:
from operator import add
average_height = reduce(add, heights) / len(heights)
heights = [x['рост'] for x in people if 'рост' in x]
if heights:
average_height = sum(heights) / len(heights)
for i in range(len(names)):
names[i] = random.choice(code_names)
for name in names:
names[names.index(name)] = random.choice(code_names)
for i, _ in enumerate(names):
names[i] = random.choice(code_names)
for i in range(len(names)):
for i in names. Но если требуется именно цикл по списку/кортежу со знанием ключа текущего элемента, то такая конструкция вполне приемлема. Во-первых, в ней нет ничего плохого. Во-вторых, она смотрится не хуже, чем предложенное выше
names.index(name), и не имеет присущих этому варианту недостатков. for i in range(len(names)) здесь используются как примеры того, «как не надо писать» (конечно же, в контексте функционального программирования). for i, _ in enumerate(names). Вы собираетесь использовать итератор с сущностями, которые вам не нужны. Это просто лишнее усложнение. В вашем же примере вводится еще и новое имя name, которое не нужно. static PyObject *
builtin_map(PyObject *self, PyObject *args)
{
typedef struct {
PyObject *it; /* the iterator object */
int saw_StopIteration; /* bool: did the iterator end? */
} sequence;
PyObject *func, *result;
sequence *seqs = NULL, *sqp;
Py_ssize_t n, len;
register int i, j;
n = PyTuple_Size(args);
if (n < 2) {
PyErr_SetString(PyExc_TypeError,
"map() requires at least two args");
return NULL;
}
func = PyTuple_GetItem(args, 0);
n--;
if (func == Py_None) {
if (PyErr_WarnPy3k("map(None, ...) not supported in 3.x; "
"use list(...)", 1) < 0)
return NULL;
if (n == 1) {
/* map(None, S) is the same as list(S). */
return PySequence_List(PyTuple_GetItem(args, 1));
}
}
/* Get space for sequence descriptors. Must NULL out the iterator
* pointers so that jumping to Fail_2 later doesn't see trash.
*/
if ((seqs = PyMem_NEW(sequence, n)) == NULL) {
PyErr_NoMemory();
return NULL;
}
for (i = 0; i < n; ++i) {
seqs[i].it = (PyObject*)NULL;
seqs[i].saw_StopIteration = 0;
}
/* Do a first pass to obtain iterators for the arguments, and set len
* to the largest of their lengths.
*/
len = 0;
for (i = 0, sqp = seqs; i < n; ++i, ++sqp) {
PyObject *curseq;
Py_ssize_t curlen;
/* Get iterator. */
curseq = PyTuple_GetItem(args, i+1);
sqp->it = PyObject_GetIter(curseq);
if (sqp->it == NULL) {
static char errmsg[] =
"argument %d to map() must support iteration";
char errbuf[sizeof(errmsg) + 25];
PyOS_snprintf(errbuf, sizeof(errbuf), errmsg, i+2);
PyErr_SetString(PyExc_TypeError, errbuf);
goto Fail_2;
}
/* Update len. */
curlen = _PyObject_LengthHint(curseq, 8);
if (curlen > len)
len = curlen;
}
/* Get space for the result list. */
if ((result = (PyObject *) PyList_New(len)) == NULL)
goto Fail_2;
/* Iterate over the sequences until all have stopped. */
for (i = 0; ; ++i) {
PyObject *alist, *item=NULL, *value;
int numactive = 0;
if (func == Py_None && n == 1)
alist = NULL;
else if ((alist = PyTuple_New(n)) == NULL)
goto Fail_1;
for (j = 0, sqp = seqs; j < n; ++j, ++sqp) {
if (sqp->saw_StopIteration) {
Py_INCREF(Py_None);
item = Py_None;
}
else {
item = PyIter_Next(sqp->it);
if (item)
++numactive;
else {
if (PyErr_Occurred()) {
Py_XDECREF(alist);
goto Fail_1;
}
Py_INCREF(Py_None);
item = Py_None;
sqp->saw_StopIteration = 1;
}
}
if (alist)
PyTuple_SET_ITEM(alist, j, item);
else
break;
}
if (!alist)
alist = item;
if (numactive == 0) {
Py_DECREF(alist);
break;
}
if (func == Py_None)
value = alist;
else {
value = PyEval_CallObject(func, alist);
Py_DECREF(alist);
if (value == NULL)
goto Fail_1;
}
if (i >= len) {
int status = PyList_Append(result, value);
Py_DECREF(value);
if (status < 0)
goto Fail_1;
}
else if (PyList_SetItem(result, i, value) < 0)
goto Fail_1;
}
if (i < len && PyList_SetSlice(result, i, len, NULL) < 0)
goto Fail_1;
goto Succeed;
Fail_1:
Py_DECREF(result);
Fail_2:
result = NULL;
Succeed:
assert(seqs);
for (i = 0; i < n; ++i)
Py_XDECREF(seqs[i].it);
PyMem_DEL(seqs);
return result;
}
/* reduce() *************************************************************/
static PyObject *
functools_reduce(PyObject *self, PyObject *args)
{
PyObject *seq, *func, *result = NULL, *it;
if (!PyArg_UnpackTuple(args, "reduce", 2, 3, &func, &seq, &result))
return NULL;
if (result != NULL)
Py_INCREF(result);
it = PyObject_GetIter(seq);
if (it == NULL) {
PyErr_SetString(PyExc_TypeError,
"reduce() arg 2 must support iteration");
Py_XDECREF(result);
return NULL;
}
if ((args = PyTuple_New(2)) == NULL)
goto Fail;
for (;;) {
PyObject *op2;
if (args->ob_refcnt > 1) {
Py_DECREF(args);
if ((args = PyTuple_New(2)) == NULL)
goto Fail;
}
op2 = PyIter_Next(it);
if (op2 == NULL) {
if (PyErr_Occurred())
goto Fail;
break;
}
if (result == NULL)
result = op2;
else {
PyTuple_SetItem(args, 0, result);
PyTuple_SetItem(args, 1, op2);
if ((result = PyEval_CallObject(func, args)) == NULL)
goto Fail;
}
}
Py_DECREF(args);
if (result == NULL)
PyErr_SetString(PyExc_TypeError,
"reduce() of empty sequence with no initial value");
Py_DECREF(it);
return result;
Fail:
Py_XDECREF(args);
Py_XDECREF(result);
Py_DECREF(it);
return NULL;
}
def increment2(a):
print a
return a + 1
def draw_car(car_position):
print '-' * car_position
putString : String → *World → *World и getString : *World → (*World, String), и они будут чистыми «от противного» (потому что нельзя функции скормить два раза одно и то же состояние мира и посмотреть, одинаковые ли результаты получатся).Request → Response, которые дёргал грязный рантайм.getString : *World -> (*World, String) по виду тоже очень похоже на поднятую в монаду функцию getString вроде getString : IO () -> IO String, контекст описывается через *World. Могу поспорить, что и монадические законы для этой штуки будут работать, хотя доказывать сейчас лень.
Введение в функциональное программирование на Python