2011-01-11 1 views
2

Я использую python и хотел бы вернуть каждые 5 элементов из списка и поместить их в формат csv.Как вернуть каждые 5 элементов из списка в python?

Кроме того, если на итерации меньше 5 элементов, тогда мне нужно заполнить нуль, чтобы получить 5 предметов.

Я использую довольно старую версию python 2.1, которая не может быть изменена, поэтому у меня нет доступа к 'iter'.

Спасибо.

+0

Мм, должен признать, что я забыл, что было возможно в те дни ... –

+0

@user: Есть ли какой-либо причине вы все еще используете 2.1? Он был выпущен 17 апреля 2001 года. – user225312

+1

Да, используя старую версию zope. Мы переходим к новой версии и новой структуре, но для старой версии все еще нужны обновления :( – user571565

ответ

5

В том числе прокладка, это может сработать. (Есть списочные в 2.1, справа Просто посмотрел его -. Они были добавлены в версии 2.0)

a = the_list 
a += [0] * (-len(a) % 5) 
result = [a[i:i + 5] for i in range(0, len(a), 5)] 

В менее древней Python, я бы заменить последнюю строку на

result = zip(*[iter(a)] * 5) 
+0

Список входных файлов мутатов. Отбрасывает память в список строк. Не соответствует требованиям CSV. –

+0

FWIW, '(4 - (len (a) - 1)% 5)' уменьшается до '(-len (a)% 5' –

+0

@John: Я привык к семантике C'% ', но для Python это упрощение действительно возможно. –

3

Это то, что вы хотите?

rows = [] 
while a_list: 
    rows.append(a_list[:5]) 
    a_list = a_list[5:] 
+0

Я собирался предложить однострочный: items = [l [i: i + 5] для i в диапазоне (0, len (l), 5)]. Но вышеизложенное должно работать также. Интересно, может ли автор вопроса ожидать полного решения со всеми конкретными функциями, хотя (это звучит как вопрос о домашнем задании). – ehabkost

+0

@ehabkost - в python 2.1? – vartec

+0

@vartec: Я не уверен, у меня нет Python 2.1, чтобы проверить его. – ehabkost

0

это работает в python 2.4. Не уверен, что, если все это возможно в 2.1:

def to_csv(l, columns=5): 
    l = l + [0]*((columns-1) - (len(l)-1)%columns) 
    ll = [ l[i:len(l):columns] for i in range(columns) ] 
    for row in zip(*ll): print ', '.join(str(xi) for xi in row) 
+0

Это поле «[0, 1, 2, 3, 4]» на 4 нуля, и оно вообще не будет помещаться '[0, 1, 2, 3, 4, 5]'. –

+0

упс! исправленный. – Jon

+0

Все дефекты, обнаруженные в некоторых других ответах, плюс вводят пробел после запятой - менее вероятно, будут обрабатываться с помощью считывателя CSV, чем без лишнего пространства, например. «skipinitialspace» не является значением по умолчанию для csv.reader Python –

0

Код:

# 1. Doesn't mutate the input list 
# 2. Doesn't waste memory on a temporary list of rows 
# 3. Handles the CSV requirement, including quoting strings properly 

float_type = type(0.0) 

def csv_escape(pyrow, quotechar='"', delimiter=',', terminator='\r\n'): 
    outlist = [] 
    for obj in pyrow: 
     if isinstance(obj, float_type): 
      s = repr(obj) # Get full precision. BTW the csv module doesn't do this :-(
     else: 
      s = str(obj) # This may need further elaboration 
     if quotechar in s: 
      x = quotechar + s.replace(quotechar, quotechar+quotechar) + quotechar 
     elif delimiter in s or '\r' in s or '\n' in s: 
      x = quotechar + s + quotechar 
     else: 
      x = s 
     outlist.append(x) 
    return delimiter.join(outlist) + terminator 

def emit_list_in_slices(alist, file_handle, 
         slice_size=5, pad_value=0, slice_formatter=csv_escape): 
    for i in xrange(0, len(alist), slice_size): 
     row = alist[i:i+slice_size] 
     n = len(row) 
     if n and n != slice_size: 
      row.extend([pad_value] * (slice_size - n)) 
     file_handle.write(csv_escape(row)) 

if __name__ == "__main__": 
    test_list = range(9) + [1.0/11.0, 'He said "Hello"', 'foo,bar', 'zot'] 
    f = open('demo.csv', 'wb') #### Note: binary 
    emit_list_in_slices(test_list, f) 
    f.close() 

Запуск с этим Python: Python 2.1.3 (# 35, 8 апреля 2002, 17:47:50) [MSC 32 бит (Intel)] на win32:

C:\junk>\python21\python csvslice21.py 

C:\junk>more demo.csv 
0,1,2,3,4 
5,6,7,8,0.090909090909090912 
"He said ""Hello""","foo,bar",zot,0,0 
0

Я думаю, что это должно работать в Python 2.1 (я не установить его здесь, чтобы проверить). Мы оставляем входной массив немодифицированным.

# create input 
a = list(range(20, 43)) 

values = [a[i:i+5] for i in range(0, len(a), 5)] 
values[-1] += (-len(values[-1]) % 5) * [0] 
csv = [','.join([str(v) for v in vs]) for vs in values] 
Смежные вопросы