4 ms·
He does do a "map", although without using the function of that name: answers = [f(x) for x in iterable] Also, the "zip" operation gives loops that seem to
by ggchappell 15y ago
He does do a "map", although without using the function of that name:
answers = [f(x) for x in iterable]
Also, the "zip" operation gives loops that seem to me to be unable to be decomposed into map, filter, reduce. E.g., how would you print a file with line numbers using only map, filter, reduce?
Regardless, I agree with your basic point: that thinking of loops in terms of high-level loop primitives, is a Good Thing.
- settrans 15y agoLine numbering a file with reduce is straightforward: def line_number_catamorphism(fp): def accumulate(a, line): line_number, lines = a return line_number + 1, lines + [(line_number + 1, line)] return reduce(accumulate, fp, (0, []))[1] It may be worth nothing that zip can be straightforwardly expressed in terms of map as well, i.e.: zip = lambda *a: map(None, *a)
- ned_batchelder 15y agoI'm sorry, is this a joke? "straightforward"? Why would you use that code when you could implement the same thing more simply like this? def line_number_mogrifier(f): num = 0 for line in f: yield (num, line) num += 1 The functional proponents say that eventually everything will be functional, I guess I'll wait and see how that goes over. People think procedurally. Functional constructs may have some technical advantages, but if adopting them shrinks the pool of effective developers, it won't catch on.
- dustingetz 15y agodef zip(*seqs): return map(lambda *items: items, *seqs) assert [(1, 'a'), (2, 'b'), (3, 'c')] == zip([1,2,3],['a','b','c']) def count(start=0): while True: yield start start += 1 from itertools import izip, islice # lazy versions with open('/etc/passwd', 'r') as f: zipped = izip(count(), f.readlines()) for numbered in zipped: print numbered izip and islice are trivial to implement: https://github.com/dustingetz/sandbox/blob/master/etc/lazy.py https://github.com/dustingetz/sandbox/blob/master/etc/lazy.p...
- ggchappell 15y agoWell, strictly speaking, you have answered my objection. But I guess I was thinking in Haskell. If Python's map takes multiple iterables, then, yes, zip is a special case. But writing zip by mapping a function without side effects, using a "map" that works only on a single iterable (as in Haskell) strikes me as a rather different thing. So I suppose that the truth of "this loop can be written using map" depends on exactly what one means by "map".
- dustingetz 15y agointeresting. how about def head(seq): return seq[0] def rest(seq): return seq[1:] def transpose(mtx): a = map(head, mtx) b = map(rest, mtx) return [a] + ([transpose(b)] if b[0] else []) def zip(xs, ys): return transpose((xs, ys)) def zip2(*seqs): return transpose(seqs) this works but is sort of icky in python, any ideas? this is also where functional python starts to fall apart - no tail call recursion, and default data structures aren't persistent. based on a haskell solution which is nicer. http://stackoverflow.com/questions/2578930/understanding-this-matrix-transposition-function-in-haskell http://stackoverflow.com/questions/2578930/understanding-thi...