【问题标题】:Sorting large file of emails based on domain shows error基于域对电子邮件的大文件进行排序显示错误
【发布时间】:2018-02-12 13:37:58
【问题描述】:

我正在尝试使用以下逻辑根据他们拥有的域对包含电子邮件的 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'

请告诉我如何让它成功运行。

【问题讨论】:

    标签: python python-3.x file sorting


    【解决方案1】:

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

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

    或者直接在dict_keys对象上调用sorted,返回一个排序列表:

    keys = sorted(data.keys())
    

    另一方面,您应该减少这部分代码,这样就不会在每次将新键添加到 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])]))
    

    【讨论】:

    • print([v for _, v in sorted(data.items(), lambda x: x[0])]) TypeError: must use keyword argument for key function 应用您的答案后遇到此问题。
    • @JafferWilson 已更新。
    【解决方案2】:

    我将其发布为答案,因为它更易于阅读。它不会直接回答你的问题,因为它已经被回答了,而是回答一个你会在你的代码能够运行的那一刻注意到的问题。

    问题:重复的域将导致仅保存最后一个条目。线

    data[domain] = email
    

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

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

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

    【讨论】:

    • 这是一个很好的建议。我通过结合你们两个人的答案得到了答案......有点困惑选择谁的答案......:)
    • 我认为您应该选择另一个答案,因为这是您所写问题的答案;)但我想这取决于您...
    • 没问题 :) 很高兴我们能一起解决您的问题! #community
    猜你喜欢
    • 2015-05-17
    • 2014-01-07
    • 2014-11-02
    • 2019-07-18
    • 1970-01-01
    • 2018-09-16
    • 1970-01-01
    • 1970-01-01
    • 2014-06-18
    相关资源
    最近更新 更多