首先声明一下,我承认我是个很烂的程序员。我甚至不愿意承认自己是程序员。(也许这就是原因?)
因为公司转向 Flink ,所以今天决定学习一下。但是不知道为什么,看到 map()就觉得生理上的厌恶,和看见一只蟑螂一样。
其实我自己也不能理解这种厌恶--我能理解为什么自己不喜欢,因为 map()本身没有可读性,你看到这个,就得去里头看到底是调用了什么函数。但是我不知道为什么我会有生理上的厌恶。同理,我在 PySpark 里看到 map(),也会极其厌恶,尤其是配合 lambda 食用,则更加厌恶。比如说
result = map(lambda x: x["id"], data["item"])
看到一次我就恶心一次。
不知道有没有类似的朋友,你们是如何克服的?我看了一下,Flink 里似乎无法避免 map()。所以只能自己习惯了。
1
iintothewind 265 天前 那是因为你用的 Python, 强类型动态语言, 而且传入参数没有 type hint 的原因吧.
你试试用用 Scala 不就好多了. |
2
sagaxu 265 天前 跟你相反,我非常喜欢 map/filter/reduce/fold/chunk...,意图+操作,可读性强,且非常直观
|
3
levelworm OP |
4
levelworm OP @iintothewind #1
有可能,但是我觉得 Python 那段,用 list comprehension 就好很多。 |
5
aresyang 265 天前 或许了解 fold_left mnist 后就还好
|
6
netabare 265 天前 不过是个 Functor 而已。
或者也许 Python 的 lambda 语法太丑了。要是换成 map (fn x => x + 1) [1,2,3,4] 这不就清晰多了吗。 List comprehension 这玩意能出现的前提是它是个 monad ,按照那个著名的话,monad 得先是个 functor ,换句话说能写出 list comprehension 的东西,它也肯定会写得出 map……这不就变成先有鸡还是先有蛋的问题了。 |
7
sagaxu 265 天前 @levelworm map 的清晰点在于,我不必定义一个 array/list 数据结构,然后把元素转换后 append 上去,而是直接告诉数据源,对这个集合的每个元素做一个映射,得到一个新集合,剥离了数据结构实现细节。你觉得别扭,可能是因为 python 的 lambda 语法不太友好。
|
8
w568w 265 天前 是这个 map 的命名和设计都比较反直觉。看到 map 这个单词,我大脑里的反应顺序是:
1. 创建 hashmap ? 2. 创建映射? 3. 哦都不对,是 ([a], f) -> [f(a)] 然后我自然的思考顺序是「对什么做映射?」,然后扫过第一个参数,发现是个很懵逼的 lambda 或者一个变量(然后往上翻了半天才发现这个变量是一个 function ),再仔细一想才发现不对,map 的第一个参数是映射…… 参数顺序这一点非常反人体工学,因为中文这个语言先说上下文,比如会说「对某物做什么事」,而不常说「做什么事对某物」:我得先知道你在操作什么列表,然后你 lambda 函数里的各种引用、操作对我才有意义。把映射函数放在前面,对我来说是一个非常破坏阅读心智连贯性的设计。 |
11
abc612008 265 天前 建议写写 ML 语言脱敏。或者写下 scala/kotlin 这种 map 比较好看的语言 e.g. `listOf(1,2,3).map{it * 2} == listOf(2,4,6)`
|
13
mizuhashi 265 天前 @w568w 函數式語言裏面 map 的返回值可以是一個函數,而且是可以組合的,所以例如 Haskell 可以這麼寫:`(map (+1) . map (*2)) [1, 2, 3]` 輸出 [3, 5, 7]。`map (*2)`返回一個可以把每個元素*2 的函數,然後`.`可以把兩個 map 的返回值連起來。不過 python 的 map 不知道有沒有這種性質,如果沒有的話確實沒必要把函數放前面。
|
14
9LCRwvU14033RHJo 265 天前 Flink 和 Spark 之所以使用 map 是因为它们受到了谷歌最早的 MapReduce 模型的启发。
使用这一套技术编写程序,可以轻松地利用集群的计算能力。map 操作将任务分解,并分发给多台机器同时处理。而 reduce 操作则将计算结果汇总到一个节点,从而得出最终结果。 |
15
nkcfc 265 天前 via Android map 大概就是数学上的映射或者函数,当然得有个 f 和集合了,f 在前面不是很自然吗? apply 和 map 一般不同,用于支持任意多变量的函数。
|
16
nkcfc 265 天前 via Android 建议多学学数学,我现在受不了用 C 风格的代码计算这个例子,定义一个空数组,然后不断添加元素?
|
18
hefish 265 天前 支持 op 的讨厌。也支持我自己的不讨厌。
|
19
kagenomirai 265 天前 OP 只是不适应而已,就像第一次学极限的定义的时候,怎么看怎么恶心。
但后续理解了习惯了,不也一样用得飞起。 另外 python 的语法可读性我觉得太差了(太多 keyword 真影响阅读)。 当然最好的适应方式就是去学一个 ML 系的语言,学的过程中抛弃过程式的思考方式。 然后你就可以做到过程式和函数式两种思考方式之间任意切换了。 虽然只是为了一个 map 就花时间在 ML 上感觉有点浪费,不过程序员就是需要不断接受新东西(所以我本身也不喜欢程序员)。 关于 map 的命名。 其实首先登场的是 fmap ,意思是对一个 functor 进行映射。 functor 可以简单理解为一个复合数据,可以改变其中的元素同时不改变结构。 去掉 f 得到 map 的意思就是对一个特定数据映射(一般都是 list 或者 array )。 |
20
sir283 265 天前 via Android 这些动态语言的 map 跟 lambda 都不怎么好阅读,我觉得只有 C++跟 Java 的才好阅读。
|
21
iseki 265 天前 via Android 语法设计导致的吧,我也非常讨厌 Python 的 lambda ,非常丑陋。但是 Kotlin 的很美
|
22
aijam 265 天前 一直印象中 Python community 就是推荐 comprehension over map 。
map 唯一实用的场景是 zip 多个 list 的时候可以 map(fn, list1, list2, ...)。 非必要不 map |
23
NickLuan 265 天前 不习惯可能是因为 map/filter 这些函数独立出来了,如果像 js 那样挂在 array 下面会可读好一些?
|
24
guanhui07 265 天前 我也非常喜欢 map/filter/reduce/chunk...,意图+操作,可读性强,且非常直观
一个 collection 解决所有事 |
25
txhwind 265 天前 map 写前面确实反人类了,像 C# Linq 一样 data["item"].select(x => x["id"]) 感觉自然一点
|
26
TWorldIsNButThis 265 天前 via iPhone python 的 lambda 本来就恶心
|
27
clino 265 天前 要不楼主给一个感觉可读性比较好的写法?
然后可以弄一个 python 包来支持这种可读性更好的写法,这样至少自己要写的时候可以用。 |
28
TWorldIsNButThis 265 天前 via iPhone @w568w map 从来都只有映射的意思
|
29
AV1 265 天前 via Android 估计 python 作者不喜欢 lambda 和 fp ,故意把 lambda 和 map 这些设计得非常恶心。
别的语言都没那么难看。 比如 js 的 map 就爽多了。 |
30
hj960511 265 天前 |
31
ChrisFreeMan 264 天前 所以我现在只用 typescript ,hover 文档一眼就知道了。另外 python 支持 TypedDict https://peps.python.org/pep-0589/
|
32
julyclyde 264 天前 map 和 foreach 其实一码事吧
就算用 foreach 你也得进去看看到底执行了啥呀 |
33
fsdrw08 264 天前 via Android 我去年 6 月写了一段 Python map 的代码,现在看回去,已经看不懂这段代码的作用了
|
34
simenet 264 天前 你都用 python 了 还恶心啥哦
|
35
RangerWolf 264 天前 op 无需 pua 自己,觉得他恶心不是你的错
map 我也觉得很反人类,只不过可能没有 op 反感的强度高而已 我记得 effective python 里面也不推荐使用 map 函数(记错请各位轻拍) |
36
RangerWolf 264 天前 应该没记错
Item 27: Use Comprehensions Instead of map and filter |
37
lululau 264 天前 |
38
jim9606 264 天前 只针对 python
我理解 lambda 是做简单调用(单个表达式)的,例如给函数绑定参数这种没啥重用价值的事,复杂需要的应该用命名函数,不想污染命名空间也可以用内部函数,反正要命名。 另外通常 map/filter/reduce 可以展开为 for..in 循环,而且这种更好按行断点。 |
39
Yuanlaoer 264 天前
感受,没有客观对错,或者说你感受到的都可以说是“真实的”和“对的”。你觉得厌恶就是厌恶。
就算你知道还有 100 个人也厌恶,能改变你什么吗? |
40
galenjiang 263 天前
map 本来就是需要用读来确认用途的,比较好的做法,结合 pointless 来做,getId = map(lambda x: x["id"]); getId(data['item']),你连什么是函数式编程的门槛都没入,谈不上厌恶...
|
42
msg7086 263 天前
我是觉得 Python 语法丑。
什么 len(),什么 map(),然后还有一堆人绞尽脑汁为这种语法编出几条道理来…… 还有什么 lambda 只能单行这样的限制( 反正不是我的菜,除非老板摁着我的头让我写,否则还是另请高明吧。 |
43
netabare 263 天前 via iPhone
|