41

Possible Duplicate:
How can I turn a list into an array in python?

How can I turn a list such as:

data_list = [0,1,2,3,4,5,6,7,8]

into a list of lists such as:

new_list = [ [0,1,2] , [3,4,5] , [6,7,8] ]

ie I want to group ordered elements in a list and keep them in an ordered list. How can I do this?

vvvvv
  • 25,404
  • 19
  • 49
  • 81
Double AA
  • 5,759
  • 16
  • 44
  • 56
  • 4
    You ask that already less than one hour ago. –  Jul 07 '11 at 17:55
  • 1
    Sorry - I can't figure out the criterium for defining the subgroups on yur question. In your example, all numbers are "ordered" - so do you want ordered elements AND subgroups of max-lenght 3? Or just lenght 3 for each subgroup? – jsbueno Jul 07 '11 at 17:56
  • 1
    @Sentinel: Not strict duplicate, because does not involve `numpy`. But perhaps close enough. Thanks – eat Jul 07 '11 at 17:58
  • 4
    This isn't a duplicate of the referenced question at all. The solutions for `list` and `numpy.array` are entirely different. – pillmuncher Jul 07 '11 at 18:05
  • 4
    @Sentinel: You're correct that it is similar but I needed to use lists and not arrays now. When I used the np.reshape method from the previous question to revert back to a 1D array, I lost all internal grouping -- my data was not simply [1,2,3...] but a lot of 3-tuples. I needed a way to put back the organization into threes not using arrays. I think this question is thus useful on its own merit and is significantly different than the previous one. – Double AA Jul 07 '11 at 18:08
  • @Double AA: Please consider now on the feedback you have received, to more holistically describe what are you aiming for. IMHO, you will have a good starting position if you'll just expand the above comment. Thanks – eat Jul 07 '11 at 18:39
  • 1
    What I really have is a 48x365 element numpy array where each element is a list containing 3 integers. I want to be able to turn it into a 1x17520 array with all the lists intact as elements, and be able to turn it back again. The numpy.reshape method seems to break the elements into three separate integers and makes a 1x52560 array. So I either need a new way of rearranging the original array or a way of grouping the elements in the new array (which are still in order) back into lists of 3. Thanks for your help. – Double AA Jul 07 '11 at 18:52
  • 1
    AFAIU, You actually have a `numpy` array with shape (48, 365, 3) and you'll figured out that a view of it as reshaped to shape (17520, 3) will enable you to perform some (shape preserving) calculations straightforward manner. Now the reversing reshaping will be quite natural. Anyway, as I suggested, please ask a new question with detailed descriptions (of your problem). These comments may be a good starting point for such descriptions, but only a starting point. Thanks – eat Jul 07 '11 at 19:12
  • 1
    @eat Wow! Excellent point! I don't know why I didn't see that before. That solves the issue with np.reshape and now I can use that. No need for another thread. Thanks again! – Double AA Jul 07 '11 at 19:41
  • But for the `SO` community it still may be relevant to post a question including relevant part of our discussion. You actually may to post the answer you find by yourself (but let other ones first digest it decent long time). So, please, I'm encouraging you to write a clear new question about this, so all of us can benefit of it. Please note that these comments will remain in the shadows for majority of `SO` community. Thanks – eat Jul 07 '11 at 20:30

9 Answers9

90

This groups each 3 elements in the order they appear:

new_list = [data_list[i:i+3] for i in range(0, len(data_list), 3)]

Give us a better example if it is not what you want.

jsbueno
  • 99,910
  • 10
  • 151
  • 209
  • I ran into a similar situation to the above question and your code worked perfect! I've been struggling at the last stage. So glad that I could address this. – Todd Oct 28 '21 at 19:41
23

This assumes that data_list has a length that is a multiple of three

i=0
new_list=[]
while i<len(data_list):
  new_list.append(data_list[i:i+3])
  i+=3
Graham
  • 1,044
  • 1
  • 8
  • 11
8

Something like:

map (lambda x: data_list[3*x:(x+1)*3], range (3))
Hyperboreus
  • 31,997
  • 9
  • 47
  • 87
5

Based on the answer from Fred Foo, if you're already using numpy, you may use reshape to get a 2d array without copying the data:

import numpy
new_list = numpy.array(data_list).reshape(-1, 3)
Cœur
  • 37,241
  • 25
  • 195
  • 267
  • I like this, but it only works when the array has a number of elements that's a multiple of 3, otherwise it will throw a ValueError. – Nils Mackay Apr 11 '22 at 14:42
4

new_list = [data_list[x:x+3] for x in range(0, len(data_list) - 2, 3)]

List comprehensions for the win :)

ba__friend
  • 5,783
  • 2
  • 27
  • 20
1

The following function expands the original context to include any desired list of lists structure:

def gen_list_of_lists(original_list, new_structure):
    assert len(original_list) == sum(new_structure), \
    "The number of elements in the original list and desired structure don't match"
        
    list_of_lists = [[original_list[i + sum(new_structure[:j])] for i in range(new_structure[j])] \
                     for j in range(len(new_structure))]
        
    return list_of_lists

Using the above:

data_list = [0,1,2,3,4,5,6,7,8]
    
new_list = gen_list_of_lists(original_list=data_list, new_structure=[3,3,3])
# The original desired outcome of [[0,1,2], [3,4,5], [6,7,8]]

new_list = gen_list_of_lists(original_list=data_list, new_structure=[2,3,3,1])
# [[0, 1], [2, 3, 4], [5, 6, 7], [8]]
0

The below one is more optimized and quite straightforward.

data_list = [0,1,2,3,4,5,6,7,8]
result =[]
i=0
while i <(len(data_list)-2):
    result.append(data_list[i:i+3])
    i+=3
print(result)

**output**

[[0, 1, 2], [3, 4, 5], [6, 7, 8]]

Sindhukumari P
  • 324
  • 2
  • 6
0

Here is a generalized solution

import math

data_list = [0,1,2,3,4,5,6,7,8]
batch_size=3

n_batches=math.ceil(len(data_list)/batch_size)

[data_list[x*batch_size:min(x*batch_size+batch_size,len(data_list))] 
    for x in range(n_batches)]

It works even if the last sublist is not the same size as the rest (<batch_size)

-1

Do you have any sort of selection criteria from your original list?

Python does allow you to do this:

new_list = []
new_list.append(data_list[:3])
new_list.append(data_list[3:6])
new_list.append(data_list[6:])

print new_list
# Output:  [ [0,1,2] , [3,4,5] , [6,7,8] ]
Manny D
  • 20,310
  • 2
  • 29
  • 31
  • 1
    FWIW, this won't be very practical one, when you try to generalize the pattern OP described. Thanks – eat Jul 07 '11 at 17:54
  • Oh I didn't know if the OP was wondering if embedded lists were possible in Python or if there was a way to convert a list into one. – Manny D Jul 07 '11 at 17:56