почему итерируемый объект не имеет длины в Python?

Я думаю, что постоянно улучшаю свой предыдущий вопрос. По сути, мне нужно было бы разбить большой текстовый (csv) файл, чтобы отправить его в multiprocess.Pool. Для этого, я думаю, мне нужен итерируемый объект, где строки можно повторять. (см. как выполнять многопроцессорную обработку больших текстовых файлов в python?)

Теперь я понял, что сам файловый объект (или тип _io.TextIOWrapper) после открытия текстового файла повторяется построчно, поэтому, возможно, мой код фрагментации (теперь ниже, извините за отсутствие его ранее) мог бы его фрагментировать, если бы он мог получить его длина? Но если он итерируемый, почему я не могу просто назвать его длину (по строкам, а не по байтам)?

Спасибо!

def chunks(l,n):
    """Divide a list of nodes `l` in `n` chunks"""
    l_c = iter(l)
    while 1:
        x = tuple(itertools.islice(l_c,n))
        if not x:
            return
        yield x

person László    schedule 13.09.2011    source источник


Ответы (1)


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

Проблема в том, что если бы файл был длиной в гигабайты, вы, возможно, не захотели бы читать его дважды, если бы это могло помочь.

Вот почему лучше не знать длины; вот почему с файлами данных следует обращаться как с Iterable, а не как с набором/вектором/массивом, который имеет длину.

Ваш код фрагментации должен иметь возможность напрямую работать с самим файловым объектом, не зная его длины.

Однако если вы хотите узнать количество строк перед полной обработкой, у вас есть два варианта:

  1. сначала буферизовать весь файл в массив строк, а затем передать эти строки в ваш блокировщик
  2. прочтите его дважды, в первый раз отбросив все данные, просто записав строки
person Sanjay Manohar    schedule 13.09.2011
comment
Спасибо! Я надеюсь, что выиграю больше, если 8 ядер в конечном итоге будут выполнять реальную работу за счет предварительного подсчета строк. Я не вижу способа, которым мой фрагмент мог бы работать, не зная, сколько строк поместить в фрагмент и отправить в ядро. Я надеюсь, что это так же хорошо, как я могу получить в py3k: ‹stackoverflow.com/questions/845058/ - person László; 13.09.2011