如何在Python中理解groupby列表(从C#/LINQ的角度来看)

2024-06-17 06:00:11 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试切换到只使用python。我在C中使用得相当广泛的是LINQ。在这个练习中,目标是获取一组键-值对,键是每个月的,值是该月消息数的一个计数,如何使用python执行类似的操作,或者可能有什么更好的方法可以做到这一点?在

class MainClass
{
    public static void Main (string[] args)
    {
        string[] months = { "jan", "feb", "mar", "apr", "may", "jun", "jul", "aug", "sep", "oct", "nov", "dec" };

        var log = LineReader ();
        Dictionary<string, int> cumulativeMonths = new Dictionary<string, int> ();

        months.ToList ()
            .ForEach (f => {
                cumulativeMonths.Add(f, log.GroupBy(g => g.Split(' ').First().ToLower())
                    .Where(w => w.Key == f).ToList().Count());

            });                                         
    }
    public static IEnumerable<string> LineReader()
    {
        Console.WriteLine ("Hello World!");
        using (StreamReader sr = new StreamReader (File.OpenRead ("/var/log/messages"))) {

            while (!sr.EndOfStream) {

                yield return sr.ReadLine ();
            }
        }
    }
}

测试输入:

^{pr2}$

测试输出将是一个字典: {一月:64562,二月:38762}。。。。在


Tags: lognewstringdictionaryvarstaticpubliclinq
3条回答

这比您所做的要简单,而且在Python中也非常简单:

with open('/var/log/messages', 'r') as f:
    cumulative_months = {}
    for line in f:
        key = line.split()[0].lower()
        cumulative_months[key] = cumulative_months.get(key, 0) + 1

with类似于C的using,当文件超出作用域时将关闭它。python文件对象可以用作迭代器。它将一次读取并返回一行,直到到达EOF为止。(它实际上读取的内容不止一行,请参见documentation)。在

或者,正如m.wasowski所指出的,您可以将collections.Counter类用于这种类型的任务,以使事情变得更简单、更快。在

您可以使用collections.Counterdict:

from collections import Counter
with open('yourfile') as f:
    count = Counter (line.split()[0] for line in f)

很抱歉有任何错误,这是从手机写的:)

是的,这正是我自己想出的,我想我想知道是否有一种更优雅(一行式)的方法来解决这个问题:

fh = open("/var/log/messages", encoding = "ISO-8859-1")
fh.seek(0)
febMessages = [x for x in fh if x.split(' ')[0].lower() == 'feb']
len(febMessages)

相关问题 更多 >