Получение 5 верхних элементов из текстового файла, содержащего миллиарды номеров, без сохранения их в переменной - PullRequest
0 голосов
/ 03 февраля 2019
  1. Найти список из 5 лучших чисел из текстового файла, в котором хранятся миллиарды номеров.Числа либо разделены запятой, либо в новых строках. Я не могу сохранить содержимое списка в переменной из-за проблемы с памятью.
  2. Я использовал генератор, и размер пакета был равен 5. Так что каждый раз, когда я вызываюnext(result_generator) Я получаю 5 элементов из текстового файла.
  3. В первый раз, когда вызывается next(result_generator), я получу 5 элементов и отсортирую их. Я буду рассматривать их как верхние 5.
  4. В следующий раз, когда я позвоню next(result_generator), я получу еще 5. Я скомбинирую его с предыдущими 5. Я отсортирую и получу топ-5 из этих 10.
  5. Точно так же, принимая следующий5 и в сочетании с предыдущими 5, чтобы получить верхние пятьдесят, пока он next(result_generator) не вернется None.

Проблема, с которой я столкнулся, заключается в том, что генератор не работает должным образом, он не принимает следующие 5 элементов.При втором вызове next(result_generator) происходит исключение.Я пытался сделать то же самое с базой данных, там все работает нормально. Я подозреваю, что с файловой операцией есть некоторые проблемы.Я использую случайную функцию для генерации чисел и записываю ее в текстовый файл для ввода образца.

Код для генерации случайных чисел в текстовом файле:

count =500
f = open('billion.txt','w')
while(count >1):
     a = random.randint(1, 1000)
     f.write(str(a)+"\n")
     count-=1
f.close()

Код для поиска 5 лучших элементов из текстафайл:

result = []
full_list = []
final_list = []
def result_generator(batchsize=5):
    while True:
        global result
        global full_list
        global final_list
        result = sorted([int(next(myfile).rstrip()) for x in range(batchsize)], reverse=True)
        final_list = sorted(full_list + result, reverse=True)[:5]
        full_list = result.copy()
        # print("result list is : {}".format(final_list))
        if not final_list:
            break
        else:
            yield final_list


with open("billion.txt") as myfile:
    result = result_generator()
    print("datatype is :", type(result))
    print("result is ",next(result))
    for i in range (0,2):
        try:
            for each in next(result):
                print("Row {} is :".format(each))
        except StopIteration:
            print("stop iteration")
        except Exception:
            print("Some different issue")

например,

131,205,65,55,222,278,672,902,69,26 ....... миллиарды

Ожидаемый результат: [902,672,278,222,205]Фактический результат: [222,205,131,65,55]

1 Ответ

0 голосов
/ 03 февраля 2019

Почему бы не использовать heapq

С некоторым файлом, например file.txt

131
205
65
55
222
278
672
902
69
26

Вы выполняете итерацию вашего файла в обычном режиме и можете выполнить

import heapq

data = []
heapq.heapify(data)
N = 5

result = []
# Assuming numbers are each on a new line
with open('file.txt', 'r') as f:
    for line in f:
        heapq.heappush(data, int(line.strip()))
        if len(data) > N:
            heapq.heappop(data)
while data:
    result.append(heapq.heappop(data))

result.reverse()
print(result)
[902, 672, 278, 222, 205]

Вы будете использовать память O (N) и время O (MlogN), где M - это миллиарды для вашей проблемы, а N - это много старших чисел, которые вы хотите получить

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...