Преобразовать плоский список в список списка в python

Обычно вы хотите пойти наоборот, как здесь . Мне было интересно, как вы можете преобразовать плоский список в список списка, quasy reshaping array в python

В numpy вы можете сделать что-то вроде:

>>> a=numpy.aranage(9) >>> a.reshape(3,3) >>> a array([[0, 1, 2], [3, 4, 5], [6, 7, 8]]) 

Мне было интересно, как вы поступаете наоборот, и мое обычное решение – это что-то вроде:

 >>> Mylist ['a', 'b', 'c', 'd', 'e', 'f'] >>> newList = [] for i in range(0,len(Mylist),2): ... newList.append(Mylist[i], Mylist[i+1]) >>> newList [['a', 'b'], ['c', 'd'], ['e', 'f']] 

есть ли более «питонический» способ сделать это?

 >>> l = ['a', 'b', 'c', 'd', 'e', 'f'] >>> zip(*[iter(l)]*2) [('a', 'b'), ('c', 'd'), ('e', 'f')] 

Как было указано в @Lattyware, это работает только в том случае, если в каждом аргументе имеется достаточно элементов в zip функции каждый раз, когда он возвращает кортеж. Если один из параметров имеет меньше предметов, чем другие, элементы обрезаются, например.

 >>> l = ['a', 'b', 'c', 'd', 'e', 'f','g'] >>> zip(*[iter(l)]*2) [('a', 'b'), ('c', 'd'), ('e', 'f')] 

Если это так, то лучше всего использовать решение @Sven Marnach

Как работает zip(*[iter(s)]*n)

Обычно это делается с использованием рецепта itertools документации itertools :

 def grouper(n, iterable, fillvalue=None): "grouper(3, 'ABCDEFG', 'x') --> ABC DEF Gxx" args = [iter(iterable)] * n return itertools.izip_longest(fillvalue=fillvalue, *args) 

Пример:

 >>> my_list = ['a', 'b', 'c', 'd', 'e', 'f', 'g'] >>> list(grouper(2, my_list)) [('a', 'b'), ('c', 'd'), ('e', 'f'), ('g', None)] 

Другой способ создания списка списков можно упростить, как показано ниже:

 >>>MyList = ['a','b','c','d','e','f'] # Calculate desired row/col >>>row = 3 >>>col = 2 >>>NewList = [MyList[col*i : col*(i+1)] for i in range(row)] >>>NewList [['a', 'b', 'c'], ['d', 'e', 'f']] 

Этот метод может быть расширен для создания любого размера строки и столбца. Если вы выберете значения столбцов и столбцов, такие как row*col >len(MyList) , row*col >len(MyList) (строка), содержащий последнее значение в MyList , закончится там, и NewList будет просто заполнен соответствующим количеством пустых списков, чтобы удовлетворить строке / col спецификация

 >>>MyList = ['a','b','c','d','e','f','g','h'] >>>row = 3 >>>col = 3 >>>NewList = [MyList[col*i : col*(i+1)] for i in range(row)] >>>NewList [['a', 'b', 'c'], ['d', 'e', 'f'], ['g','h']] >>>row = 4 >>>col = 4 >>>NewList = [MyList[col*i : col*(i+1)] for i in range(row)] [['a', 'b', 'c', 'd'], ['e', 'f', 'g','h'], [], []] 

Если вы предпочитаете список списков, а не список кортежей из плоского списка, тогда можно сделать это:

  a = range(20) # sample starting list b = [] # new list c = [] # alternate new list # ny is length of new list. nx length of each list within it nx = 5; ny = 4 bb = 0; ee = bb + nx # option one: sliding indeces for slices. for ii in range(ny-1): bb += nx ee += nx b.append(a[bb:ee]) c.append(a[slice(ii*nx,nx*(ii+1))]) # option two, use slice() 

(Я играл со сжатием целых циклов в одну строку со списком, но не был успешным, так как я использовал его, slice () может почти доставить вас туда.) Одно из возможных преимуществ этих подходов другие упоминаются, что если ваш оригинальный, плоский список не является даже кратным размерам вашего нового, нужного списка списков, вы не потеряете никаких данных. Суть в том, что последний список будет короче всех остальных, так как он будет содержать «остатки». ни один из этих методов не кажется мне очень питоническим.