Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/355.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 2无法获取键和值(字典和元组)_Python_Python 2.7 - Fatal编程技术网

Python 2无法获取键和值(字典和元组)

Python 2无法获取键和值(字典和元组),python,python-2.7,Python,Python 2.7,[任务] 编写一个程序,通读文本文件,并计算出每一条消息在一天中按小时的分布情况。通过查找时间,然后使用冒号再次拆分字符串,可以从“from”行中提取小时 文本文件的一行示例: “劳伦。marquard@oul.ab.bc2015年1月5日星期六09:14:16“ 累积每小时的计数后,打印计数,按小时排序,如下所示 [预期结果] 04 3 06 1 07 1 09 2 10 3 11 6 14 1 15 2 16 4 17 2 18 1 19 1 这意味着我需要拉出“09:14:16”部分,然

[任务]

编写一个程序,通读文本文件,并计算出每一条消息在一天中按小时的分布情况。通过查找时间,然后使用冒号再次拆分字符串,可以从“from”行中提取小时

文本文件的一行示例:

“劳伦。marquard@oul.ab.bc2015年1月5日星期六09:14:16“

累积每小时的计数后,打印计数,按小时排序,如下所示

[预期结果]

04 3
06 1
07 1
09 2
10 3
11 6
14 1
15 2
16 4
17 2
18 1
19 1
这意味着我需要拉出“09:14:16”部分,然后再次拉出“09”小时

我将使用“#”来评论我在下面所做的工作

[我的代码]

name = raw_input("Enter file:")
if len(name) < 1 : name = "mbox-short.txt"     #if nothing is entered by user, it goes straight to the desired file
handle = open(name, 'r')     # open and read the file
count = dict()     # initialise count to a empty dictionary
for text in handle:     #for loop to loop through lines in the file
    text = text.rstrip()     #r.strip() to to remove any newline "\n"
    if not text.startswith('From '): continue     # find lines that starts with "From "
    text = text.split()         #split the line into list of words
    line = text[5]              #time is located at the [5] index
    time = line.split(':')     #split once more to get the hour 
    hour = time[0]            #hour is on the [0] index    
    count[hour] = count.get(hour, 0) + 1
    print count        
谁能帮我一下我哪里出了问题?我的方向对吗?
感谢您的反馈和建议,我是编程新手,请对任何格式错误保持温和和抱歉。

由于datetime的格式始终相同,您可以使用虚拟方法:

your_string[-13:11] # your hour

其中,您的_字符串是您粘贴的字符串,但包含完整日期时间的每个文本对此操作都有效。

删除
打印计数
,并在循环的末尾和外部添加以下行:

for key in sorted(count.keys()):
    print key, count[key]   

我认为,如果你真的想要输出,而不是你需要的最后的“打印计数”(在循环之外):


您的问题是,您正在打印一个字典,而字典不是用Python排序的(实际上是这样,但不是按键值排序的,所以这是一个没有意义的问题)

您可以通过在打印结果之前对字典键进行排序来解决此问题,正如所建议的那样。但就我个人而言,我不确定这是不是最好的解决方案

原因是你在处理数字。此外,您正在处理[0,23]范围内的数字。这对我来说简直就是“使用列表”。:-)

因此,不要使用dict(),请尝试使用:

# count = dict()
count = [0] * 24
这将创建一个包含24项的列表,索引范围从0到23

现在,您从字符串解析中得到的也是字符串,因此您需要将它们转换为数字:

# count[hour] = count.get(hour, 0) + 1
count[int(hour)] += 1
请注意,获取无法转换为整数或不在0..23范围内的小时将如何在dict中工作,但在预初始化列表中失败。这实际上是好的:接收错误输入并使用它生成错误输出而不引起投诉的代码是糟糕的代码。当然,仅仅抛出异常的代码也不是很好的代码,但这是朝着正确方向迈出的一步

当然,还会出现另一个问题:如果打印dict,它的键和值都会被打印出来。如果打印列表,则只打印值。因此,我们需要将输出代码更改为:

for hour, amount in enumerate(count):
    print hour, ':', amount
我想在你们的代码中指出的下一点是:你们绝对确定你们的电子邮件地址不包含空格吗?您的代码总是有可能遇到如下行:

From: "Bob Fisher" <bob@fishers.org> Sat Jan 5 09:14:16 2015
使用正则表达式可能更为通用,但这是一个更高级的主题,我将在这里不赘述:如果你知道正则表达式,你将能够轻松地完成它,如果你不知道,你最好有一个适当的介绍,而不是我在这里所能拼凑的任何东西

另一个吹毛求疵的地方:我注意到你没有关闭你的文件句柄。这不是一个大问题,因为您的程序无论如何都会终止,任何仍然打开的文件句柄都会自动关闭。然而,在较大的项目中,这可能会导致问题。您的代码可能会被其他代码调用,如果您的代码生成异常,并且该异常被调用方处理或抑制,则文件句柄将保持打开状态。重复足够的次数,程序将超过操作系统对最大打开文件数的限制

因此,我建议使用稍微不同的语法打开文件:

with open(name, 'r') as handle:
    for text in handle:
        # ...
这种语法的优点是,“with”将正确地关闭文件句柄,无论下面的代码中发生了什么。即使发生异常,文件仍将正确关闭

到目前为止,代码如下所示:

name = raw_input("Enter file:")
if not name: name = "mbox-short.txt" # cleaner check for empty string
count = [0] * 24 # use pre-initialized list instead of dict
with open(name, 'r') as handle: # use safer syntax to open files
    for text in handle:
        text = text.rstrip()
        if not text.startswith('From '): continue
        text = text.split()
        line = text[-2] # use 2nd item from the end, just to be safe
        time = line.split(':')
        hour = int(time[0]) # we treat hour as integer
        count[hour] += 1 # nicer looking
for hour, amount in enumerate(count):
    if amount: # Only print hours with non-zero counters
        print hour, ':', amount

现在,有一些方法可以将它的大小至少减少一半(可能更多),但我一直在努力使所有内容保持简单并符合原始代码的精神。

我不明白输出的问题是什么,您能更明确一点吗?顺便说一句,看看这个模块,它似乎很适合这里。我也可以在排序中使用k,v(count.items()):print k,voh my这是一个很长的模块,我还没有学会模仿,但是,无论如何,谢谢你的帮助,真的很感谢
import re
import collections

name = raw_input("Enter file:")
if not name: name = "mbox-short.txt"

with open(name) as handle:
    hours = re.findall(r'^From .*(\d{2}):\d{2}:\d{2}', handle.read(), re.M)

count = sorted(collections.Counter(hours).items(), key=lambda x: int(x[0]))

for h, c in count:
    print h, c
with open(name, 'r') as handle:
    for text in handle:
        # ...
name = raw_input("Enter file:")
if not name: name = "mbox-short.txt" # cleaner check for empty string
count = [0] * 24 # use pre-initialized list instead of dict
with open(name, 'r') as handle: # use safer syntax to open files
    for text in handle:
        text = text.rstrip()
        if not text.startswith('From '): continue
        text = text.split()
        line = text[-2] # use 2nd item from the end, just to be safe
        time = line.split(':')
        hour = int(time[0]) # we treat hour as integer
        count[hour] += 1 # nicer looking
for hour, amount in enumerate(count):
    if amount: # Only print hours with non-zero counters
        print hour, ':', amount
import re
import collections

name = raw_input("Enter file:")
if not name: name = "mbox-short.txt"

with open(name) as handle:
    hours = re.findall(r'^From .*(\d{2}):\d{2}:\d{2}', handle.read(), re.M)

count = sorted(collections.Counter(hours).items(), key=lambda x: int(x[0]))

for h, c in count:
    print h, c