根据域对大型电子邮件文件进行排序显示错误

时间:2017-09-04 10:19:33

标签: python python-3.x file sorting

我正在尝试使用以下逻辑对包含电子邮件的1 GB文件进行排序:

data = {}
emails = open('test','r',encoding='ascii',errors='ignore')
for email in emails.readlines():
    (user, domain) = email.split('@')
    data[domain] = email
    keys = data.keys()
    keys.sort()
print([data[x] for x in keys])

当我使用Python 3.5运行文件时,我收到以下错误:

    keys.sort()
AttributeError: 'dict_keys' object has no attribute 'sort'

请告诉我怎么做才能让它成功运行。

2 个答案:

答案 0 :(得分:6)

您需要在返回的list对象上调用dict_keys,将其转换为具有list.sort方法的列表:

keys = list(data.keys())
keys.sort()

或者直接在sorted对象上直接调用dict_keys以返回已排序的列表:

keys = sorted(data.keys())

另一方面,你应该考虑这部分代码,这样每次将新密钥添加到dict时,都不会进行排序,但是在循环结束时。

如果您实际上不需要密钥列表,只需直接在dict上应用sorted

for email in emails.readlines():
    (user, domain) = email.split('@')
    data[domain] = email
print([v for _, v in sorted(data.items(), key=lambda x: x[0])]))

答案 1 :(得分:2)

我将此作为答案发布,因为它更容易阅读。它没有直接回答您的问题,因为它已经得到了回答,但是在回答问题时您会注意到您的代码能够运行的那一刻。

问题:重复的域只会导致最后一个条目被保存。这条线

data[domain] = email

覆盖之前在该键下写入的内容。你想要做的是替换这个块提到的行:

try:
    data[domain].append(email)
except KeyError:
    data[domain] = [email]

这将创建同一域上的用户列表。如果找不到密钥,则会引发KeyError,这表示它是一个新域,您必须创建另一个列表。如果找到密钥,我们只需附加新电子邮件。