在这段Python代码中,用C#实现带有闭包的动态类

本文关键字:实现 闭包 动态 Python 代码 | 更新日期: 2023-09-27 18:25:56

我想读取一个以制表符分隔的文件,其中第一行是标题
此实现的目标是在尝试进行以下索引工作时,不浪费内存和时间为每一行创建字典:line[column_name]
这是我的Python实现:

def readf(filename):
    for i, line in enumerate(open(filename)):
        cols = line.strip().split(''t')
        if i==0:
            class Line:
                _header = {col: i for i, col in enumerate(cols)}
                def __init__(self, data):
                    self.data = data
                def __getitem__(self, key):
                    return self.data[self._header[key]]
        else:
            yield Line(cols)
if __name__ == "__main__":
    ll = []
    for line in readf("hello.tsv"):
        ll.append(line["col1"])

这能在C#中以类似的方式实现吗
我是C#的新手,从我搜索到的内容来看,它不支持在函数中定义类
C#中的闭包在网络上似乎没有有用的资源
感谢

编辑:前面的实现需要3.3秒,下面的实现对于一个1GB的文件需要4秒,其中大约有1M行

from itertools import izip
def readf(filename):
    header = []
    for i, line in enumerate(open(filename)):
        cols = line.strip().split(''t')
        if i==0:
            header = list(cols)
        else:
            yield {header:cols for header,cols in izip(header, cols)}
if __name__ == "__main__":
    ll = []
    for line in readf("hello.tsv"):
        ll.append(line["col1"])

在这段Python代码中,用C#实现带有闭包的动态类

根据讨论,有几种方法可以实现这一点:

词典列表:

        List<Dictionary<string, string>> aLines = new List<Dictionary<string, string>>();
        var aFile = File.ReadAllLines(filename);
        var aColumns = aFile.First().Split(''t');
        aFile.Skip(1).ToList().ForEach(line =>
        {
            var aSplitLine = line.Split(''t');
            Dictionary<string, string> aDictionary = new Dictionary<string, string>();
            for (int i = 0; i < aSplitLine.Length; i++)
            {
                aDictionary.Add(aColumns[i], aSplitLine[i]);
            }
            aLines.Add(aDictionary);
        });
        int row = 0;
        string fieldValueExample = aLines[row]["field_Value"];

或者通过创建顺序查找:

        var aFile = File.ReadAllLines(filename);
        int anIndex = 0;
        var aColumns = aFile.First().Split(''t').ToDictionary(field => field,field => anIndex++);
        var aFileData = aFile.Skip(1).Select(line => line.Split(''t')).ToList();
        var row = 0;
        string fieldValueExample = aFileData[row][aColumns["field_Value"]];

我还没有看过编译后的输出,但我认为第二个输出在技术上更快,但由于导入过程中执行的操作较少,因此以可读性为代价。不过,在读取字段值时,权衡可能是您正在查看两个索引以得出字段值。

最后,我不愿意像这样预先优化。做你可读和可维护的事情,以及谁将首先帮助你,看看这是否能完成任务。在大多数环境中,没有人会注意到运行时间延长了几秒钟。

或者。。或者,如果您试图获得与.Net的互操作性(而不是端口到C#的要求),您可以始终使用Iron Python。

http://ironpython.net/