0

Given a list

lst=['a','a','b','b','b','c','d','d']

and a list 'l' containing partition numbers

l=[2,3,1,2]

what I want is

partitioned_lst=[['a','a'],['b','b','b'],['c'],['d','d']]
  • 1
    What have you tried so far? – theherk Apr 21 '22 at 07:28
  • 2
    Is it a coincidence that the characters are grouped? If not, you can use [`itertools.groupby`](https://docs.python.org/3/library/itertools.html#itertools.groupby). https://stackoverflow.com/questions/773/how-do-i-use-itertools-groupby – Peter Wood Apr 21 '22 at 07:42

6 Answers6

1
partitioned_lst=[]
i=0
for n in l:
    partitioned_lst.append(lst[i:i+n])
    i+=n
partitioned_lst
1

One liner just for fun

print([lst[sum(l[:index]):sum(l[:index])+num] for index, num in enumerate(l)])
1

If you can't use groupby (see Peter Wood's comment) because you need l:

lst=['a','a','b','b','b','c','d','d']
l=[2,3,1,2]

it = iter(lst)
result = [[next(it) for _ in range(n)] for n in l]
Timus
  • 10,974
  • 5
  • 14
  • 28
1
lst=['a','a','b','b','b','c','d','d']
l=[2,3,1,2]
s = 0
Res=[]
for i in l:
  Res.append(lst[s: s+i])
  s += i
print(Res)

Output

[['a', 'a'], ['b', 'b', 'b'], ['c'], ['d', 'd']]
0

For fun, here is a solution using the relatively new assignment expressions (python ≥ 3.8):

x=0
partitioned_lst = [lst[x:(x:=x+y)] for y in l]

NB. I wouldn't use this in production code as it depends on the outer scope

output:

[['a', 'a'], ['b', 'b', 'b'], ['c'], ['d', 'd']]
mozway
  • 194,879
  • 13
  • 39
  • 75
-1

Here is one that works for arbitrary iterables:

>>> from itertools import islice
>>> [list(islice(it, n)) for it in [iter(lst)] for n in l]
[['a', 'a'], ['b', 'b', 'b'], ['c'], ['d', 'd']]
>>>

Although, probably would be cleaner as a generator:

def partition_by(iterable, partitions):
    it = iter(iterable)
    for n in partitions:
        yield list(islice(it, n))

And use like:

>>> list(partition_by(lst, l))
[['a', 'a'], ['b', 'b', 'b'], ['c'], ['d', 'd']]

Note, this approach will not error out and keep going if the iterator is exhausted:

>>> list(partition_by(lst, [10, 10, 10]))
[['a', 'a', 'b', 'b', 'b', 'c', 'd', 'd'], [], []]

If this behavior is undesirable:

def partition_by(iterable, partitions, strict=True):
    it = iter(iterable)
    for n in partitions:
        part = list(islice(it, n))
        if not part and strict:
            raise ValueError("iterable ran out of items early")
        yield part

Would do it.

Type annotated:

import typing
from collections.abc import Iterable

def partition_by(
    iterable: Iterable[T], 
    partitions: Iterable[int], 
    strict: bool=True
) -> Iterable[list[T]]:
    it = iter(iterable)
    for n in partitions:
        part = list(islice(it, n))
        if not part and strict:
            raise ValueError("iterable ran out of items early")
        yield part
juanpa.arrivillaga
  • 88,713
  • 10
  • 131
  • 172