I have one, two, or more lists of the same length inside of another list, like so:
list1 = [['0900', '0930', 'M', None, None, None, None]]
list2 = [['0930', '1050', 'M', None, None, None, None], ['0930', '1050', None, None, 'W', None, None]]
list3 = [['1200', '1250', 'M', None, 'W', None, None], ['1200', '1250', None, None, None, 'Th', None], ['1200', '1250', None, None, None, None, 'F']]
The first two elements are guaranteed to be the same. I'd like to merge them to one list with the max()
of each other position, like so:
list1 = ['0900', '0930', 'M', None, None, None, None]
list2 = ['0930', '1050', 'M', None, 'W', None, None]
list3 = ['1200', '1250', 'M', None, 'W', 'Th', 'F']
How do I best go about that? Apparently you can't do a max()
when comparing to a None
.
CodePudding user response:
You can use zip()
with list unpacking to make element-wise groupings. Then, to get the maximum among each group, you can check whether there exists any element that isn't None
using any()
:
- If such an element exists, you can get the max among all non-
None
elements usingmax()
andfilter()
. - If not, you can just output
None
.
This gives us:
[max(filter(lambda x: x is not None, sublist))
if any(sublist) else None for sublist in zip(*lst)]
For example:
list1 = [['0900', '0930', 'M', None, None, None, None]]
list2 = [
['0930', '1050', 'M', None, None, None, None],
['0930', '1050', None, None, 'W', None, None]
]
list3 = [
['1200', '1250', 'M', None, 'W', None, None],
['1200', '1250', None, None, None, 'Th', None],
['1200', '1250', None, None, None, None, 'F']
]
result = []
for lst in [list1, list2, list3]:
result.append([max(filter(lambda x: x is not None, sublist))
if any(sublist) else None for sublist in zip(*lst)])
print(result)
This outputs:
[['0900', '0930', 'M', None, None, None, None],
['0930', '1050', 'M', None, 'W', None, None],
['1200', '1250', 'M', None, 'W', 'Th', 'F']]
CodePudding user response:
Why do you need the max()
of each position? If all elements except one are None
, you can just take the first non-None
value in the group.
def first_not_none(iterable):
for i in iterable:
if i is not None: return i
Then,
>>> combined1 = [first_not_none(group) for group in zip(*list1)]
['0900', '0930', 'M', None, None, None, None]
>>> combined2 = [first_not_none(group) for group in zip(*list2)]
['0930', '1050', 'M', None, 'W', None, None]
>>> combined3 = [first_not_none(group) for group in zip(*list3)]
['1200', '1250', 'M', None, 'W', 'Th', 'F']