在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中的迭代实现相同的代码,或者更少的代码?
注意:如果我不需要(Any,Count,First),我不想将iterable实现为列表。
答案 0 :(得分:7)
最初的问题是如何在Python中使用可迭代项实现相同的功能。尽管我喜欢列表理解,但在许多情况下,我仍然发现LINQ更具可读性,直观性和简洁性。以下库包装了Python可迭代程序,以使用相同的LINQ语义在Python 中实现相同的功能:
如果您要坚持使用内置Python功能,Linq提供了C#LINQ功能到内置Python命令的相当全面的映射。
答案 1 :(得分:4)
以下Python行应该与你拥有的相同(假设代码中为func
或lambda
,返回一个布尔值):
# 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_
。< / p>
请注意,您也可以使用map()
代替理解/生成器,但通常认为它不太可读。
答案 2 :(得分: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中编写示例的方式。