我刚刚发现列表的映射是在例如Python和Haskell就是这样完成的:
newlist = map(function, somelist)
例如Kotlin和Dart就是这样完成的:
newlist = somelist.map(function)
我想知道每个解决方案相对于另一个解决方案有什么优势? Python / Haskell实现更“功能”不是吗?
答案 0 :(得分:3)
Python map
并不适用于列表;它适用于任何可迭代的。 Python不使用单独的map
方法向不同的类添加(或向map
添加无效object
方法并多次覆盖它),而是使用可迭代的协议;任何实现__iter__
的类(提供实现__next__
的对象)都可以与map
一起使用。
答案 1 :(得分:3)
它与“更多功能”无关,只是其中一种用法。
Haskell没有方法,所以
newlist = map function somelist
是写它的唯一方法。
在Python中,map
不保留iterable的结构,而是创建一个新列表(Python2)或一个新的map对象(Python3)。它只是一个常规函数,它可以将任何可迭代对象作为参数,因此它不会附加到特定对象。 (另一方面,map
并不是一个特别受欢迎的函数,它被认为更加“pythonic”使用列表或生成器理解。)
在Kotlin中,所有迭代实现方法map
。与Python不同,它只是一个常规函数,它是一个常规(可覆盖)方法,并且可以这样使用。
真正的区别在于,在Kotlin中,我们可以用更优化的版本覆盖它,而在Python中我们不能。这可能是更多的OOP,但它的功能并没有那么差。
答案 2 :(得分:2)
这有些基于意见,我选择的语言是Python,但我会给它一个机会。
Python非常重视对鸭子的打字,特别是对于可迭代和序列协议。
当您致电map(function, some_iterable)
时,至少在概念上 - 并不重要some_iterable
类型的重要性,只要您可以逐个从中提取值,以便将函数应用于每个他们。它可以是一个列表,一个元组,一个字符串,或一个生成器...具有全局map
函数可确保所有这些都可以工作,甚至可以通过实现{{来迭代自编写的类1}}。
在我看来,在__iter__
中实现可迭代协议更为优雅,它解锁了大量功能,而不是编写自己的YourClass
函数或不得不调用YourClass.map
}。
另一个例子是list(YourClass_instance).map(function)
方法。为什么我们写str.join
而不是"sep".join(my_list)
?事实上,在构建结果字符串时,如果从列表,集合,元组或任何其他可迭代类型中提取值,您并不十分关心。 my_list.join(sep)
接受任何可迭代的内容。
str.join
是内置函数。序列(通常是大多数容器)可以使用len
公开其项目数量,只要它们实施len(my_container)
方法,您就不必猜测它是__len__
,my_container.len()
或my_container.num_items()
。
Here是本次讨论的相关文章。
答案 3 :(得分:2)
Python / Haskell实现更“功能”不是吗?
不多。 Kotlin语法不太适合构图,但是......
您可以将方法调用链接在一起(例如(map f . map g) somelist
),而不是撰写(例如somelist.map(f).map(g)
)。这要求链接对象支持map
,因此如果您要编写自己的列表组合器,则必须将它们注入该对象。由于Kotlin支持extension methods,您仍然可以避免耦合数据类型和高阶列表组合器(这在面向对象编程中通常是一个缺点)。