Это вопрос об относительных достоинствах быстрого кода, который использует стандартную библиотеку, но неясен (по крайней мере для меня) по сравнению с альтернативой, созданной вручную. В этом потоке (и других, которые он дублирует), кажется, что "Pythonic" способ разделить список на группы - это использовать itertools, как в первой функции в примере кода ниже (немного измененном из ΤΖΩΤΖΙΟΥ ).
Причина, по которой я предпочитаю вторую функцию, заключается в том, что я могу понять, как она работает, и если мне не нужно заполнение (например, превращение последовательности ДНК в кодоны), я могу воспроизвести ее из памяти в одно мгновение.
Скорость лучше с itertools. В частности, если нам не нужен список назад или мы хотим заполнить последнюю запись, itertools работает быстрее.
Какие есть еще аргументы в пользу стандартного библиотечного решения?
from itertools import izip_longest
def groupby_itertools(iterable, n=3, padvalue='x'):
"groupby_itertools('abcde', 3, 'x') --> ('a','b','c'), ('d','e','x')"
return izip_longest(*[iter(iterable)]*n, fillvalue=padvalue)
def groupby_my(L, n=3, pad=None):
"groupby_my(list('abcde'), n=3, pad='x') --> [['a','b','c'], ['d','e','x']]"
R = xrange(0,len(L),n)
rL = [L[i:i+n] for i in R]
if pad:
last = rL[-1]
x = n - len(last)
if isinstance(last,list):
rL[-1].extend([pad] * x)
elif isinstance(last,str):
rL[-1] += pad * x
return rL
время:
$ python -mtimeit -s 'from groups import groupby_my, groupby_itertools; L = list("abcdefghijk")' 'groupby_my(L)'
100000 loops, best of 3: 2.39 usec per loop
$ python -mtimeit -s 'from groups import groupby_my, groupby_itertools; L = list("abcdefghijk")' 'groupby_my(L[:-1],pad="x")'
100000 loops, best of 3: 4.67 usec per loop
$ python -mtimeit -s 'from groups import groupby_my, groupby_itertools; L = list("abcdefghijk")' 'groupby_itertools(L)'
1000000 loops, best of 3: 1.46 usec per loop
$ python -mtimeit -s 'from groups import groupby_my, groupby_itertools; L = list("abcdefghijk")' 'list(groupby_itertools(L))'
100000 loops, best of 3: 3.99 usec per loop
Редактировать: Я бы изменил здесь имена функций (см. Ответ Алекса), но их так много, что я решил вместо этого опубликовать это предупреждение.