Возможность хранить 1000 файлов одновременно - это отдельная проблема, которая зависит от вашей ОС и ее конфигурации; в противном случае вам придется выполнить два шага - объединить группы из N файлов во временные, а затем объединить временные в файл конечного результата (достаточно двух шагов, так как они позволяют объединить всего N в квадрате файлы, если N равно не менее 32, поэтому должно быть возможно объединение 1000 файлов). В любом случае, это отдельная проблема от задачи «объединить N входных файлов в один выходной файл» (это только вопрос того, вызываете ли вы эту функцию один раз или несколько раз).
Общая идея этой функции - сохранить приоритетную очередь (модуль heapq
хорош в этом ;-) с небольшими списками, содержащими «ключ сортировки» (текущий TLD, в вашем случае), за которым следует последняя строка чтение из файла, и, наконец, открытый файл, готовый для чтения следующей строки (и что-то отличное между ними, чтобы гарантировать, что нормальный лексикографический порядок не приведет к случайной попытке сравнить два открытых файла, что приведет к ошибке). Я думаю, что некоторый код, вероятно, лучший способ объяснить общую идею, поэтому затем я отредактирую этот ответ, чтобы предоставить код (однако у меня нет времени на тестирование его, поэтому примите его как псевдокод, предназначенный для донести идею; -).
import heapq
def merge(inputfiles, outputfile, key):
"""inputfiles: list of input, sorted files open for reading.
outputfile: output file open for writing.
key: callable supplying the "key" to use for each line.
"""
# prepare the heap: items are lists with [thekey, k, theline, thefile]
# where k is an arbitrary int guaranteed to be different for all items,
# theline is the last line read from thefile and not yet written out,
# (guaranteed to be a non-empty string), thekey is key(theline), and
# thefile is the open file
h = [(k, i.readline(), i) for k, i in enumerate(inputfiles)]
h = [[key(s), k, s, i] for k, s, i in h if s]
heapq.heapify(h)
while h:
# get and output the lowest available item (==available item w/lowest key)
item = heapq.heappop(h)
outputfile.write(item[2])
# replenish the item with the _next_ line from its file (if any)
item[2] = item[3].readline()
if not item[2]: continue # don't reinsert finished files
# compute the key, and re-insert the item appropriately
item[0] = key(item[2])
heapq.heappush(h, item)
Конечно, в вашем случае, в качестве функции key
вам понадобится функция, которая извлекает домен верхнего уровня по строке имени домена (с завершающим символом новой строки) - в предыдущем вопросе вы уже указали модулю urlparse как предпочтительнее для манипулирования строками для этой цели. Если вы настаиваете на манипуляции со строками,
def tld(domain):
return domain.rsplit('.', 1)[-1].strip()
или что-то в этом роде, вероятно, является разумным подходом при этом ограничении.
Если вы используете Python 2.6 или выше, heapq.merge является очевидной альтернативой, но в этом случае вам нужно подготовить итераторы самостоятельно (включая гарантию того, что «объекты открытого файла» никогда не будут сравниваться случайно ...) с аналогичным подходом «украсить / украсить» из того, что я использую в более переносимом коде выше.