Reputation: 1045
I've a function returning list from list of lists where the return list groups members of each list by index numbers. Code and example:
def listjoinervar(*lists: list) -> list:
"""returns list of grouped values from each list
keyword arguments:
lists: list of input lists
"""
assert(len(lists) > 0) and (all(len(i) == len(lists[0]) for i in lists))
joinedlist = [None] * len(lists) * len(lists[0])
for i in range(0, len(joinedlist), len(lists)):
for j in range(0, len(lists[0])):
joinedlist[i//len(lists[0]) + j*len(lists[0])] = lists[i//len(lists[0])][j]
return joinedlist
a = ['a', 'b', 'c']
b = [1, 2, 3]
c = [True, False, False]
listjoinervar(a, b, c)
# ['a', 1, True, 'b', 2, False, 'c', 3, False]
Are there ways to make this more Pythonic using itertools, generators, etc? I've looked at examples like this but in my code there is no interaction b/w the elements of the individual lists. Thanks
Upvotes: 3
Views: 1092
Reputation: 26039
Use itertools.chain.from_iterable
+ zip
:
from itertools import chain
def listjoinervar(*a):
return list(chain.from_iterable(zip(*a)))
Usage:
>>> a = ['a', 'b', 'c']
>>> b = [1, 2, 3]
>>> c = [True, False, False]
>>> listjoinervar(a, b, c)
['a', 1, True, 'b', 2, False, 'c', 3, False]
Upvotes: 7
Reputation: 3489
Using zip
and list comprehension:
from typing import List, Any
def listjoinervar(*args: List[Any]) -> List[Any]:
return [item for sublist in list(zip(*args)) for item in sublist]
Usage:
>>> a = ["a", "b", "c"]
>>> b = [1, 2, 3]
>>> c = [True, False, False]
>>> listjoinervar(a,b,c)
['a', 1, True, 'b', 2, False, 'c', 3, False]
The use of type annotations is optional.
Upvotes: 1
Reputation: 5011
You can do this without having to import anything, using the enumerate
and max
methods:
def custom_group(*args):
biggest, result = max(args, key = lambda x: len(x)), []
for (i, value) in enumerate(biggest):
for arr in args:
if len(arr) > i:
result.append(arr[i])
return result
You're looping through the biggest list and adding each value from each list at that index (if it exists) to the results list then moving on to the next index until the loop stops.
Using your specified arrays:
a = ["a", "b", "c"]
b = [1, 2, 3]
c = [True, False, False]
You'd call the function, like this:
print(custom_group(a,b,c))
Which should result in the following list being outputted:
["a", 1, True, "b", 2, False, "c", 3, False]
Good luck.
Upvotes: 0
Reputation: 19885
In a normal situation, I would also use itertools.chain
, as in Austin's answer.
However, just for completeness, an alternative solution that does not import anything:
def join_lists(*a):
return [element for sub in zip(*a) for element in sub]
a = ['a', 'b', 'c']
b = [1, 2, 3]
c = [True, False, False]
join_lists(a, b, c)
Output:
['a', 1, True, 'b', 2, False, 'c', 3, False]
Upvotes: 3