apexprogramming
apexprogramming

Reputation: 433

Append list every Nth index from another list and repeat based on the number of elements

I have two lists:

gizmos = [('gizmo1', 314),
          ('gizmo1', 18),
          ('gizmo1', 72),
          ('gizmo1', 2),
          ('gizmo1', 252),
          ('gizmo1', 314),
          ('gizmo1', 18),
          ('gizmo1', 72),
          ('gizmo1', 2),
          ('gizmo1', 252),
          ('gizmo1', 314),
          ('gizmo1', 18),
          ('gizmo1', 72),
          ('gizmo1', 2),
          ('gizmo1', 252)]

owner =  ['owner1','owner3','owner32']

My goal result is to combine both lists into a new list, as such. I want the first element to repeat N number of times based on owner length, and then continue for the next elements. In this case owner length = 3

    gizmos = [('owner1','gizmo1', 314),
              ('owner1','gizmo1', 18),
              ('owner1','gizmo1', 72),
#start appending second element from list
              ('owner3','gizmo1', 2),
              ('owner3','gizmo1', 252),
              ('owner3','gizmo1', 314),
#start appending third element from list

              ('owner32','gizmo1', 18),
              ('owner32','gizmo1', 72),
              ('owner32','gizmo1', 2)]

I attempted to zip the 2 lists but due to the lengths not matching this does not work.

Upvotes: 1

Views: 73

Answers (3)

MennoK
MennoK

Reputation: 488

You can do it by first creating a list where the owners are repeated <length> times, then zipping. For example:

gizmos = [('gizmo1', 314),
          ('gizmo1', 18),
          ('gizmo1', 72),
          ('gizmo1', 2),
          ('gizmo1', 252),
          ('gizmo1', 314),
          ('gizmo1', 18),
          ('gizmo1', 72),
          ('gizmo1', 2),
          ('gizmo1', 252),
          ('gizmo1', 314),
          ('gizmo1', 18),
          ('gizmo1', 72),
          ('gizmo1', 2),
          ('gizmo1', 252)]

owner =  ['owner1','owner3','owner32']
length=3

## create a list where each owner is repeated [length] times
repeated_owners = [x for x in owner for i in range(length)]
## then zip
result = [(x, *y) for x, y in zip(repeated_owners, gizmos)]
print(result)

Result:

[('owner1', 'gizmo1', 314), 
 ('owner1', 'gizmo1', 18), 
 ('owner1', 'gizmo1', 72), 
 ('owner3', 'gizmo1', 2), 
('owner3', 'gizmo1', 252), 
('owner3', 'gizmo1', 314), 
('owner32', 'gizmo1', 18), 
('owner32', 'gizmo1', 72), 
('owner32', 'gizmo1', 2)]

Upvotes: 1

Dani Mesejo
Dani Mesejo

Reputation: 61910

You could do use the grouper recipe from itertools:

import pprint
from itertools import zip_longest


def grouper(iterable, n, fillvalue=None):
    "Collect data into fixed-length chunks or blocks"
    # grouper('ABCDEFG', 3, 'x') --> ABC DEF Gxx"
    args = [iter(iterable)] * n
    return zip_longest(*args, fillvalue=fillvalue)


res = [(o, *gizmo) for group, o in zip(grouper(gizmos, 3), owner) for gizmo in group]

pprint.pprint(res)

Output

[('owner1', 'gizmo1', 314),
 ('owner1', 'gizmo1', 18),
 ('owner1', 'gizmo1', 72),
 ('owner3', 'gizmo1', 2),
 ('owner3', 'gizmo1', 252),
 ('owner3', 'gizmo1', 314),
 ('owner32', 'gizmo1', 18),
 ('owner32', 'gizmo1', 72),
 ('owner32', 'gizmo1', 2)]

Upvotes: 1

Z Li
Z Li

Reputation: 4318

Use np.repeat to get ['owner1', 'owner1', 'owner1','owner2',...]

[(x[0], *x[1]) for x in zip( *[np.repeat(owner, len(owner)), gizmos])]
[('owner1', 'gizmo1', 314),
 ('owner1', 'gizmo1', 18),
 ('owner1', 'gizmo1', 72),
 ('owner3', 'gizmo1', 2),
 ('owner3', 'gizmo1', 252),
 ('owner3', 'gizmo1', 314),
 ('owner32', 'gizmo1', 18),
 ('owner32', 'gizmo1', 72),
 ('owner32', 'gizmo1', 2)]

If you don't like numpy:

sum([[x]*len(owner) for x in owner], [])

This works similar to np.repeat(owner, len(owner))

Upvotes: 1

Related Questions