2016-04-26 9 views
1

У меня есть большой файл, заполненный целыми числами, разделенными пробелом и запятой. Я пытаюсь читать в 1 КБ за раз и преобразовывать его в список целых чисел.преобразовать список строк из файла в список целых чисел

Этот код работает отлично:

with open('test_age.txt', 'r+') as inf: 
    with open('test_age_out.txt', 'r+') as outf: 
     sorted_list =[] 
     a = [x.strip() for x in inf.read(1000).split(',')] 
     int_a = map(int, a) 
     f = tempfile.TemporaryFile() 
     outf_array = sorted(int_a) 
     f.write(str(outf_array)) 
     f.seek(0) 
     #etc... 

выход:

[1, 1, 2, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, etc... 

Но когда я добавляю в цикле в то время, чтобы прочитать следующую 1KB:

with open('test_age.txt', 'r+') as inf: 
    with open('test_age_out.txt', 'r+') as outf: 
     sorted_list =[] 
     while True: 
      a = [x.strip() for x in inf.read(1000).split(',')] 
      int_a = map(int, a) 
      if not a: 
       break 
      f = tempfile.TemporaryFile() 
      outf_array = sorted(int_a) 
      print outf_array 
      f.write(str(outf_array)) 
      f.seek(0)  

Я получаю выход и ValueError:

[1, 1, 2, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 
8, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 12, 12, 12, 
12, 12, 12, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 15, 15, 16, 17, 18, 
19, 19, 20, 20, 20, 20, 21, 21, 22, 22, 22, 23, 23, 24, 24, 24, 24, 25, 
25, 25, 25, 25, 26, 26, 26, 26, 27, 27, 27, 28, 28, 29, 30, 30, 30, 30, 
31, 31, 31, 32, 32, 33, 33, 33, 33, 33, 33, 34, 34, 34, 34, 34, 35, 35, 
35, 35, 35, 36, 36, 37, 37, 37, 37, 38, 38, 39, 39, 39, 39, 39, 39, 40, 
40, 40, 40, 41, 41, 42, 43, 43, 43, 44, 44, 44, 44, 44, 45, 46, 46, 46, 
46, 47, 47, 47, 47, 47, 48, 48, 48, 48, 48, 48, 49, 49, 49, 50, 50, 50, 
50, 50, 50, 51, 51, 51, 51, 51, 51, 52, 52, 52, 52, 52, 52, 53, 53, 54, 
54, 54, 55, 55, 55, 55, 56, 56, 56, 56, 56, 57, 57, 57, 57, 58, 58, 58, 
59, 59, 60, 60, 60, 61, 62, 62, 62, 62, 63, 63, 63, 63, 63, 63, 63, 64, 
64, 64, 65, 66, 66, 67, 67, 67, 67, 68, 68, 68, 68, 68, 69, 69, 69, 69, 
69, 69, 69, 70, 70, 70, 70, 71, 71, 72, 72, 73, 74, 74, 74, 75, 76, 76, 
76, 76, 77, 77, 77, 77, 78, 78, 79, 79, 79, 79, 81, 81, 81, 81, 82, 82, 
82, 82, 82, 83, 83, 83, 83, 84, 85, 85, 85, 85, 86, 86, 86, 87, 87, 87, 
87, 87, 87, 88, 88, 88, 88, 88, 88, 88, 89, 89, 89, 89, 90, 90, 90, 91, 
91, 91, 91, 91, 91, 91, 92, 92, 93, 93, 93, 94, 94, 94, 94, 95, 95, 
96, 96, 96, 97, 97, 98, 99, 100, 100, 100, 100, 100] 
[2, 3, 3, 3, 3, 4, 4, 5, 5, 6, 8, 9, 10, 10, 11, 11, 11, 11, 12, 12,12, 
13, 14, 15, 17, 17, 17, 17, 17, 17, 18, 18, 18, 20, 21, 22, 22, 22, 22, 
23, 23, 24, 24, 24, 26, 27, 27, 27, 27, 28, 28, 29, 29, 29, 29, 30, 32, 
32, 32, 32, 33, 33, 34, 34, 36, 37, 37, 37, 37, 38, 39, 41, 41, 42, 43, 
44, 44, 46, 46, 47, 48, 49, 49, 49, 49, 51, 51, 52, 52, 52, 52, 53, 54, 
54, 54, 55, 55, 56, 60, 60, 61, 61, 61, 62, 63, 63, 64, 65, 65, 65, 65, 
66, 66, 67, 68, 68, 68, 70, 70, 73, 73, 73, 74, 74, 75, 75, 75, 77, 77, 
77, 77, 78, 78, 78, 78, 79, 80, 81, 81, 82, 82, 83, 83, 83, 83, 84, 84, 
85, 85, 85, 85, 86, 87, 88, 90, 91, 91, 91, 92, 93, 93, 93, 94, 95, 97, 
98, 98, 99, 100] 
    int_a = map(int, a) 
ValueError: invalid literal for int() with base 10: '' 

Я не уверен, почему это происходит. Если я вызываю печать, кажется, что списки ARE создаются и сортируются. Однако ValueError существует. Что дает?

+0

Ну, пустая строка не является допустимым основанием 10 целое число, вот почему. Вы могли бы спросить: 'if a:' * before * вы делаете 'int_a = map (int, a)' и/или проверяете/удаляете пустые строки. – jDo

+2

Возможно, вы не получаете правильно сформированную строку для каждых 1000 байтов? Он будет работать правильно с одноразрядными номерами, но если он начнет меняться, вы получите кусочки и кусочки, оставшиеся с частями цифр и запятыми, висящими сами по себе. – TigerhawkT3

+0

. 'a = [int (x) для x в inf.read (1000) .split (','), если x.strip(). isdigit()]', если вы работаете только с целыми числами – jDo

ответ

1

Посмотрите на выходе str.split с сдавшим разделителем, появляющиеся на голове или хвосте строки:

>>> ', 3, 5'.split(', ') 
['', '3', '5'] 

Это пустая строка, что пытается ваша программа (и отсутствие), чтобы разобрать как целое. ''.strip() не помогает (и не обязательно для int(), кстати - он автоматически игнорирует ведущие и конечные пробелы). Я рекомендую читать блоки, которые гарантированно будут полными и действительными, например строки. Если файл является только одной большой строкой, вам придется выполнить дополнительную работу, чтобы сохранить последние символы из строки и переместить их в обработку следующей строки. Не забудьте обработать оставшиеся символы после цикла.

line = inf.read(1000) 
new += line 
current, delimiter, new = line.rpartition(', ') 
# process current 
# continue loop to add more content 

Если файл может умещаться в памяти вашей системы, вы можете просто прочитать весь файл и разбить его на одном дыхании:

numbers = map(int, inf.read().split(', ')) 
+0

Благодарим вас за быстрый ответ и подробное объяснение.Файл WAY к большому, чтобы вписаться в память, и я нахожусь в процессе обучения/реализации External Merge Sort для решения этой конкретной проблемы. Еще раз спасибо! Приветствия. –

Смежные вопросы