Reputation: 433
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
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
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
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