Сценарий Python: как вырезать вывод на ограниченный размер строки?

Я использую скрипт python для отделения домена от соответствующих писем, а затем группируя электронные письма в соответствии с их соответствующим доменом. Следующий сценарий работает для меня:

#!/usr/bin/env python3
from operator import itemgetter
from itertools import groupby
import os
import sys

dr = sys.argv[1]


for f in os.listdir(dr):
    write = []
    file = os.path.join(dr, f)
    lines = [[l.strip(), l.split("@")[-1].strip()] for l in open(file).readlines()]
    lines.sort(key=itemgetter(1))
    for item, occurrence in groupby(lines, itemgetter(1)):
        func = [s[0] for s in list(occurrence)]
        write.append(item+","+",".join(func))
    open(os.path.join(dr, "grouped_"+f), "wt").write("\n".join(write))

Я использовал: python3 script.py /path/to/input files Вход, который я дал, был списком писем и получил его как:

domain1.com,gemail1@domain1.com,email2@domain.com
domain2.com,email1@domain2.com,email2@domain2.com,email3@domain2.com

Но что проблема, с которой сталкивается, связана с лимитом MongoDB. Поскольку у MongoDB есть ограничение на размер документа размером 16 МБ, а одна строка в моем выходном файле рассматривается как 1 документ от MongoDB, а размер строки не должен превышать 16 МБ. Так что я хочу, чтобы результат должен быть ограничен 21 электронной почтой на домен, и если в домене больше писем, то он должен быть напечатан на новой строке с остальными электронными письмами (опять же, если электронные письма превышают 21, а затем новую строку с тем же именем домена). Я купил дубликаты данных в mongoDB.

Итак, окончательный вывод должен выглядеть примерно так:

domain1.com,email1@domain1.com,email2@domain1.com,... email21@domain1.com
domain1.com,email22@domain1.com,.....
domain2.com,email1@domain2.com,....

Точка (.) в приведенном выше примере представляет много текста, которые я нарезал, чтобы сделать его простым для понимания , Надеюсь, это прояснит мою проблему и надеется получить решение для этого.

1
задан 28 January 2017 в 17:26

1 ответ

Чтобы поддерживать произвольные большие каталоги и файлы, вы могли использовать файлы os.scandir() один за другим и обрабатывать файлы по строкам:

#!/usr/bin/env python3
import os

def emails_with_domain(dirpath):
    for entry in os.scandir(dirpath):
        if not entry.is_file():
            continue  # skip non-files
        with open(entry.path) as file:
            for line in file:
                email = line.strip()
                if email:  # skip blank lines
                    yield email.rpartition('@')[-1], email  # domain, email

Чтобы группировать адреса электронной почты по домену, не более 21 письмо на строку, вы могли бы использовать os.scandir() :

import sys
from collections import defaultdict

dirpath = sys.argv[1]
with open('grouped_emails.txt', 'w') as output_file:
    emails = defaultdict(list)  # domain -> emails
    for domain, email in emails_with_domain(dirpath):
        domain_emails = emails[domain]
        domain_emails.append(email)
        if len(domain_emails) == 21:
            print(domain, *domain_emails, sep=',', file=output_file)
            del domain_emails[:]  # clear

    for domain, domain_emails in emails.items():
        print(domain, *domain_emails, sep=',', file=output_file)

Примечание:

все электронные письма сохраняются в тех же строках файла с тем же домен не обязательно смежны

См. Что является наиболее «питоновым»? способ перебора списка в кусках?

1
ответ дан 23 May 2018 в 01:59
  • 1
    Некоторая хорошая мысль. Я тоже попробую. :) – Jaffer Wilson 30 January 2017 в 09:08

Другие вопросы по тегам:

Похожие вопросы: