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?
source to share
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)]
>>>
source to share
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')]
source to share
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']]
source to share
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.)
source to share