【问题标题】:Python equivalents to LINQPython 等价于 LINQ
【发布时间】:2012-08-16 01:01:28
【问题描述】:

在 C# 中,使用 LINQ,如果我有枚举 enumerable,我可以这样做:

// a: Does the enumerable contain an item that satisfies the lambda?
bool contains = enumerable.Any(lambda);

// b: How many items satisfy the lambda?
int count = enumerable.Count(lambda);

// c: Return an enumerable that contains only distinct elements according to my custom comparer
var distinct = enumerable.Distinct(comparer);

// d: Return the first element that satisfies the lambda, or throws an exception if none
var element = enumerable.First(lambda);

// e: Returns an enumerable containing all the elements except those
// that are also in 'other', equality being defined by my comparer
var except = enumerable.Except(other, comparer);

我听说 Python 的语法比 C# 更简洁(因此效率更高),那么我如何在 Python 中使用相同或更少的代码来实现相同的迭代?

注意:如果不需要,我不想将可迭代对象具体化为列表(AnyCountFirst)。

【问题讨论】:

    标签: python functional-programming iterator


    【解决方案1】:

    以下 Python 行应该与您所拥有的相同(假设您的代码中的 funclambda 返回一个布尔值):

    # Any
    contains = any(func(x) for x in enumerable)
    
    # Count
    count = sum(func(x) for x in enumerable)
    
    # Distinct: since we are using a custom comparer here, we need a loop to keep 
    # track of what has been seen already
    distinct = []
    seen = set()
    for x in enumerable:
        comp = comparer(x)
        if not comp in seen:
            seen.add(comp)
            distinct.append(x)
    
    # First
    element = next(iter(enumerable))
    
    # Except
    except_ = [x for x in enumerable if not comparer(x) in other]
    

    参考文献:

    请注意,我将lambda 重命名为func,因为lambda 是Python 中的关键字,并且出于同样的原因,我将except 重命名为except_

    请注意,您也可以使用 map() 代替推导式/生成器,但通常认为它的可读性较差。

    【讨论】:

    • 谢谢,你错过了 d: enumerable.First(lambda),你能加吗?
    • @Flavien - 添加它,我还修改了 enumerable.Distinct 等效项。我的原始版本是提供一组比较器结果,而不是使用原始枚举中的值。
    • 没有自定义比较器,你可以使用distinct = set(enumerable)
    • 性能怎么样?它和 .Net 等效吗?
    • 为什么是sum() 而不是len()
    【解决方案2】:

    最初的问题是如何在 Python 中使用可迭代实现相同的功能。尽管我很喜欢列表推导,但我仍然发现 LINQ 在许多情况下更具可读性、直观性和简洁性。以下库包装了 Python 可迭代对象以在 Python 中实现相同的功能具有相同的 LINQ 语义

    如果您想坚持使用内置 Python 功能,this blog post 提供了 C# LINQ 功能到内置 Python 命令的相当彻底的映射。

    【讨论】:

      【解决方案3】:

      我们有生成器表达式和各种函数,用于在可迭代对象上表达任意条件。

      any(some_function(e) for e in iterable)
      sum(1 for e in iterable if some_function(e))
      set(iterable)
      next(iterable)
      (e for e in iterable if not comparer(e) in other)
      

      大致对应于您使用惯用 Python 编写示例的方式。

      【讨论】:

        猜你喜欢
        • 2017-02-14
        • 1970-01-01
        • 2010-10-12
        • 2011-02-04
        • 2011-02-11
        • 2015-01-25
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多