Reputation: 31
this is what i have for the lists broken from a 2d list:
[0, 0, 0, 0, 0, 3, 3, 3]
[0, 0, 0, 0, 2, 0, 0, 0, 2]
[0, 0, 0, 1, 0, 0, 0, 0, 0, 1]
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1]
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2, 0, 0, 0, -2]
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -3, -3, -3]
and because they are broken from the same list, I don't know how to add them into a new list.
Do I append them into a new list and zip them? But how do I append them(because they are from the same list, if I use index[3], it will only come out with the number in each line(for example, 0 for index[3],line1))
This is what I expect:
[ 0, 0, 0, 1, 2, 3, 3, 3, 2, 1, 0, -1, -2, -3, -3, -3, -2, -1, 0, 0, 0 ]
that is , all the numbers with the same index got add together.
Please give me some hint. Thank you!
Upvotes: 0
Views: 83
Reputation: 188
welp, it looks from the example that the items that go to the target list do not overlap by their indicies in the source lists- if it is guaranteed you can do something like this:
list_of_lists = [ # broken list 1
[[0, 0, 0, 0, 0, 3, 3, 3],
[0, 0, 0, 0, 2, 0, 0, 0, 2],
[0, 0, 0, 1, 0, 0, 0, 0, 0, 1],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2, 0, 0, 0, -2],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -3, -3, -3]],
[# broken list 1
[0, 0, 0, 0, 0, 3, 3, 3],
[0, 0, 0, 0, 2, 0, 0, 0, 2],
[0, 0, 0, 1, 0, 0, 0, 0, 0, 1],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2, 0, 0, 0, -2],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -3, -3, -3]],
]
def combine_broken_list(lists):
max_size = max(map(len, lists)) # get target list size
result = [0] * max_size # initialize target list to zeros - if nothing target is zero, then this will stay that way
for sublist in lists:
found_ix = 0 # when we find a nonzero, we know we do not need to look before it again, since we start at 0.
for i, x in enumerate(sublist[found_ix:]):
if x != 0: # iterate and find non zeros
found_ix = i
result[i] = sublist[i] # set target value to source value
return result
# run on several broken lists
result = list(map(combine_broken_list, list_of_lists))
print(result) # show result
# test result 1
tgt = [0, 0, 0, 1, 2, 3, 3, 3, 2, 1, 0, -1, -2, -3, -3, -3, -2, -1, 0, 0, 0 ]
print(result[0] == tgt)
# >True
If that guarantee does not exist, then what are the precedence rules?
There is probably a more efficient solution with numpy, but this should work.
Upvotes: 0
Reputation: 2622
You can use itertools.zip_longest.
Make an iterator that aggregates elements from each of the iterables. If the iterables are of uneven length, missing values are filled-in with fillvalue. Iteration continues until the longest iterable is exhausted.
from itertools import zip_longest
num_lists = [[0, 0, 0, 0, 0, 3, 3, 3],
[0, 0, 0, 0, 2, 0, 0, 0, 2],
[0, 0, 0, 1, 0, 0, 0, 0, 0, 1],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2, 0, 0, 0, -2],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -3, -3, -3]]
result = [sum(lst) for lst in zip_longest(*num_lists, fillvalue=0)]
print(result)
[0, 0, 0, 1, 2, 3, 3, 3, 2, 1, 0, -1, -2, -3, -3, -3, -2, -1, 0, 0, 0]
>>>
Upvotes: 1