与python等价的c#版本itertools.izip_longest
本文关键字:itertools izip longest 版本 python | 更新日期: 2023-09-27 18:13:59
我想弄清楚是否有内置支持压缩两个不同长度的IEnumerables,而不会丢失c#中较大列表中的元素。
基本上我正在寻找Python(>= 2.6)版本的izip_longest
从itertools
在c#。
我也开放其他漂亮的自定义解决方案使用LINQ
来获得相同的功能。为了进一步说明,
如果a = [1, 2, 3]
和b = [4, 5, 6, 7]
,期望的输出应该是[[1, 4], [2, 5], [3, 6], [7]]
我自己编写了一个遍历IEnumerable<T>
的zip扩展方法:
public static IEnumerable<T[]> Zip<T>(this IEnumerable<T> left, IEnumerable<T> right)
{
IEnumerator<T> leftEnumerator = left.GetEnumerator();
IEnumerator<T> rightEnumerator = right.GetEnumerator();
bool hasLeft = leftEnumerator.MoveNext();
bool hasRight = rightEnumerator.MoveNext();
while (hasLeft || hasRight)
{
if (hasLeft && hasRight)
{
yield return new T[] { leftEnumerator.Current, rightEnumerator.Current };
}
else if (hasLeft)
{
yield return new T[] { leftEnumerator.Current };
}
else if (hasRight)
{
yield return new T[] { rightEnumerator.Current };
}
hasLeft = leftEnumerator.MoveNext();
hasRight = rightEnumerator.MoveNext();
}
}
你可以这样调用它:
int[] a = new int[] { 1, 2, 3 };
int[] b = new int[] { 4, 5, 6, 7 };
IEnumerable<int[]> zipped = a.Zip(b);
LINQ本身有一个Zip方法,用于组合两个序列中的元素,并对它们应用一个函数(可以简单地将元素组合成一对)。结果与最短序列一样长。
MoreLINQ库为LINQ添加了几个扩展,包括MaxBy
, ExceptBy
和各种Zip策略,包括返回最短(Zip),最长(ZipLongest)或不匹配失败(EquiZip)。
文档中的示例显示ZipLongest将返回缺失元素的默认值:
int[] numbers = { 1, 2, 3 };
string[] letters = { "A", "B", "C", "D" };
var zipped = numbers.ZipLongest(letters, (n, l) => n + l);
/// ... will yield "1A", "2B", "3C", "0D" in turn.
您可以从Nuget下载单个操作符(例如ZipLongest)的代码或二进制包,或者您可以下载整个库的二进制包。