16.5. 数据中心思想编程
Description: Python from novice to pro
Keywords: Python, Dive Into Python, tutorial, object-oriented, programming, documentation, book, free

# 深入 Python :Dive Into Python 中文版 Python 从新手到专家 [Dip_5.4b_CPyUG_Release] | Find:

## 16.5. 数据中心思想编程

现在的你，可能正抓耳挠腮地狠想，为什么这样比使用 `for` 循环和直接调用函数好。这是一个非常好的问题。通常这是一个程序观问题。使用 `map` 和 `filter` 强迫你围绕数据进行思考。

就此而言，你从没有数据开始，你所做的第一件事是获得当前脚本的目录路径，并获得该目录中的文件列表。这就是关键的一步，使你有了待处理的真实数据：文件名列表。

当然，你知道你并不关心所有的文件，而只关心测试套件。你有太多数据，因此你需要过滤(`filter`)数据。你如何知道哪些数据应该保留？你需要一个测试来确定，因此你定义一个测试并把它传给 `filter` 函数。这里你应用了一个正则表达式来确定，但无论如何构建测试，原则是一样的。

现在你有了每个测试套件的文件名 (且局限于测试套件，因为所有其他内容都被过滤掉了)，但是你还需要以模块名来替代之。你有正确数量的数据，只是格式不正确。因此，你定义了一个函数来将文件名转换为模块名，并使用这个函数映射整个列表。从一个文件名，你可以获得一个模块名，从一个文件名列表，你可以获得一个模块名列表。

如果不应用 `filter`，你也可以使用 `for` 循环结合一个 `if` 语句的方法。`map` 的使用则可以由一个 `for` 循环和一个函数调用来取代。但是 `for` 循环看起来像是个繁重的工作。至少，简单讲是在浪费时间，糟糕的话还会隐埋 Bug。例如，你需要弄清楚如何测试这样一个条件：“这个文件是测试套件吗？”这是应用特定的逻辑，没有哪个语言能自动为我们写出其代码。但是一旦你搞清楚了，你还需要费尽周折地定义一个新的空列表，写一个 `for` 循环以及一个 `if` 语句并手工地调用 `append` 将符合条件的元素一个个添加到新列表中，然后一路上注意区分哪个变量里放着过滤后的数据，哪个变量里放着未过滤的老数据。为什么不直接定义测试条件，然后由 Python 为你完成接下来的工作呢？

当然啦，你可以尝试眩一点的做法，去删除列表中的元素而不新建一个列表。但是你以前吃过这样的亏。试图在循环中改变数据结构是很容易出问题的。Python 是一个这样工作的语言吗？用多长时间你才能搞清这一点？你能确定记得你第二次这样尝试的安全性？程序员在和这类纯技术课题较劲的过程中，花费了太多的时间，犯了太多的错误，却并没有什么意义。这样并不可能令你的程序有所进步，只不过是费力不讨好。

我在第一次学习 Python 时是抵触列表解析的，而且我抗拒 `filter` 和 `map` 的时间更长。我坚持着我更艰难的生活，固守着类似于 `for` 循环和 `if` 语句以及一步步地以代码为中心的编程方式。而且我的 Python 程序看起来很像是 Visual Basic 程序，细化每一个函数中的每一个操作步骤。它们却有着同样的小错误和隐蔽的 Bug。这一切其实都没有意义。

让这一切都远去吧。费力不讨好的编程不重要，数据重要。并且数据并不麻烦，它们不过就是数据。如果多了，就过滤。如果不是我们要的，就映射。聚焦在数据上，摒弃费力的劳作。