Adding and creating chunks of a list in python

This is my list

list1 = [1,2,3,4,5,6,7,8,9,10,11,12]

      

I tried to do this

it = iter(list1)

chunked_lists =  zip(it,it,it)

chunked_lists is now = [(1,2,3),(4,5,6),(7,8,9),(10,11,12)]

      

Now I would like to add "data" to each chunk so that it looks like

[(1,2,3,'data'),(4,5,6,'data')....etc]

      

but tuples are immutable and I will have to destroy, add and create them again.

is there a better way to accomplish this in python?

+2


source to share


5 answers


it = iter(list1)
from itertools import repeat
chunked_lists =  zip(it,it,it,repeat("data"))
[(1, 2, 3, 'data'), (4, 5, 6, 'data'), (7, 8, 9, 'data'), (10, 11, 12, 'data')]

      



+5


source


You can use itertools.repeat

to create a new iterator containing data

and then apply a function zip

to the previous iterators and a new re-iterator:

>>> it = iter(list1)
>>> it2=repeat('data',len(list1))
>>> chunked_lists =  zip(it,it,it,it2)
>>> chunked_lists
[(1, 2, 3, 'data'), (4, 5, 6, 'data'), (7, 8, 9, 'data'), (10, 11, 12, 'data')]
>>> 

      

Please note that as @Padraic Cunningham mentioned in his answer , there is no need to call the function len

in itertools.repeat

. So you can just userepeat('data')



If you want to modify the list of tuples after creation, you can use a list comprehension to modify your tuples by adding new elements to the tuples.

Example:

>>> import numpy as np
>>> l2=np.random.randint(0,100,len(list1)/3)
>>> it = iter(list1)
>>> chunked_lists =  zip(it,it,it)
>>> chunked_lists = [i+(j,) for i,j in zip(chunked_lists,l2)]
>>> l2
array([35, 22, 35, 95])
>>> chunked_lists
[(1, 2, 3, 35), (4, 5, 6, 22), (7, 8, 9, 35), (10, 11, 12, 95)]
>>> 

      

+3


source


It should be in a linear way:

list1 = [1,2,3,4,5,6,7,8,9,10,11,12]
result = [tuple(list1[x:x+3]+["data"]) for x in range(0, len(list1), 3)]

      

Unless I ignore some Python complexity, since tuple () has O (n) complexity , slice accessory has O (k) complexity , and the overhead invoked +["data"]

is nothing more than just adding a node at the end of the list (this O(1)

), it should be O((len(list1) / k) * k ^ 2)

aka O(n k)

where k

fixed to 3. In your case.

result = [tuple(list1[x:x+3]+["data"]) for x in range(0, len(list1), 3)]

      

means:

[list1[x:x+3]+["data"] for x in (0, 3, ... 12)]

aka:

[
 tuple(list1[0:3]+["data"]),
 tuple(list1[4:6]+["data"]),
 ...
 tuple(list1[9:12]+["data"])
]

      

It also behaves well with odd lists:

>>> list1 = [1,2,3,4,5,6,7,8,9,10,11]
>>> print [tuple(list1[x:x+3]+["data"]) for x in range(0, len(list1), 3)]
[(1, 2, 3, 'data'), (4, 5, 6, 'data'), (7, 8, 9, 'data'), (10, 11, 'data')]

      

+1


source


Since tuples are immutable, if you add and remove them frequently, you might be better off using lists of lists:

list1 = [1,2,3,4,5,6,7,8,9,10,11,12]
it = iter(list1)
chunked_lists = [list(a) for a in zip(it,it,it)]  
# => [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]]

for l in chunked_lists:
    l.append('data')
# => [[1, 2, 3, 'data'], [4, 5, 6, 'data'], [7, 8, 9, 'data'], [10, 11, 12, 'data']]

      

+1


source


How to add them to a function zip

when creating itself chunked_lists

-

>>> list1 = [1,2,3,4,5,6,7,8,9,10,11,12]
>>> it = iter(list1)
>>> chunked_lists =  zip(it,it,it,['data']*(len(list1)/3))
>>> chunked_lists
[(1, 2, 3, 'data'), (4, 5, 6, 'data'), (7, 8, 9, 'data'), (10, 11, 12, 'data')]

      


For Python 3.x, you need to split len(list1)

using an operator //

(so that it returns an int). (And most likely wrap zip

in list()

, since zip

Python 3.x returns an iterator.)

0


source







All Articles