4

以这个简单的C# LINQ查询为例,想象这db.Numbers是一个包含一列的SQLNumber表:

var result = 
    from n in db.Numbers
        where n.Number < 5
        select n.Number;

这将在C#中非常有效地运行,因为它会生成类似的SQL查询

select Number from Numbers where Number < 5 

没有做的是从数据库中选择所有数字,然后在C#中过滤它们,就像它最初看起来那样。

Python支持类似的语法:

result = [n.Number for n in Numbers if n.Number < 5]

但是这里的if子句在客户端而不是服务器端进行过滤,效率要低得多。

Python中是否有与LINQ一样高效的东西?(我目前正在评估Python vs. IronPython vs. Boo,因此适用于任何这些语言的答案都很好。)

4

6 回答 6

6

sqlalchemy中的 sqlsoup 为您提供了 python 中最快的解决方案,我认为如果您想要一个清晰的(ish)单线。看看页面就知道了。

它应该是这样的......

result = [n.Number for n in db.Numbers.filter(db.Numbers.Number < 5).all()]
于 2008-09-23T00:52:48.563 回答
5

仔细查看SQLAlchemy。这可能可以做很多你想要的。它为您提供了在服务器上运行的普通 SQL 的 Python 语法。

于 2008-09-22T21:35:01.127 回答
5

LINQ 是 C# 和 VB.NET 的语言特性。它是编译器识别并特殊处理的特殊语法。它还依赖于另一种称为表达式树的语言特性。

表达式树有点不同,它们不是特殊的语法。它们的编写方式与任何其他类实例化一样,但编译器确实通过将 lambda 转换为运行时抽象语法树的实例化来特别处理它们。这些可以在运行时进行操作以生成另一种语言(即 SQL)的命令。

C# 和 VB.NET 编译器采用 LINQ 语法,并将其转换为 lambda,然后将其传递给表达式树实例。然后有一堆框架类可以操纵这些树来生成 SQL。您还可以找到其他提供“LINQ 提供程序”的库,包括 MS 生产的和第三方的,它们基本上弹出一个不同的 AST 处理器来从 LINQ 生成除 SQL 之外的东西。

因此,用另一种语言做这些事情的一个障碍是它们是否支持运行时 AST 构建/操作。我不知道 Python 或 Boo 是否有任何实现,但我还没有听说过任何此类功能。

于 2008-09-22T21:40:10.977 回答
4

我相信当 IronPython 2.0 完成时,它将支持 LINQ(有关示例讨论,请参阅此线程)。现在你应该可以写出类似的东西:

Queryable.Select(Queryable.Where(someInputSequence, somePredicate), someFuncThatReturnsTheSequenceElement) 

IronPython 2.0b4 中可能会有更好的东西——目前有很多关于如何处理命名冲突的讨论。

于 2008-09-23T00:11:39.660 回答
1

LINQ 的一个关键因素是编译器生成表达式树的能力。我在 Nemerle 中使用了一个宏,它将给定的 Nemerle 表达式转换为表达式树对象。然后我可以将它传递给 IQueryables 上的 Where/Select/etc 扩展方法。它不是 C# 和 VB 的语法,但对我来说已经足够接近了。

我通过这篇文章的链接获得了 Nemerle 宏: http ://groups.google.com/group/nemerle-dev/browse_thread/thread/99b9dcfe204a578e

应该可以为 Boo 创建一个类似的宏。然而,鉴于您需要支持大量可能的表达式,这是一项相当多的工作。Ayende 在这里给出了概念证明:http: //ayende.com/Blog/archive/2008/08/05/Ugly-Linq.aspx

于 2008-10-25T01:12:45.710 回答
1

Boo 支持使用与 python 相同的语法的列表生成器表达式。有关这方面的更多信息,请查看有关生成器表达式列表推导的 Boo 文档。

于 2008-10-31T18:55:58.060 回答