How to pad 0s to garantee same length while iterating over two lists?

Question:

My inputs are :

x = ['A', 'B', 'B', 'C', 'D', 'D', 'D']
y = [ 4 ,  3 ,  5 ,  9 ,  1 ,  6 ,  2 ]

And I’m just trying to make this dictionnary.

{'A': [4, 0, 0], 'B': [3, 5, 0], 'C': [9, 0, 0], 'D': [1, 6, 2]}

The logic : we collect the values and pad 0 x times to reach a length equal to the max length of letters (3 here for D).

I made the code below but I got a different result :

from collections import Counter

c = Counter(x)
max_length = c.most_common()[0][-1]

my_dict = {}
for ix, iy in zip(x,y):
    my_dict[ix] = [iy] + [0 for _ in range(max_length-1)]
    
{'A': [4, 0, 0], 'B': [5, 0, 0], 'C': [9, 0, 0], 'D': [2, 0, 0]}

Can you tell what’s wrong with it please ?

Asked By: VERBOSE

||

Answers:

One possible solution is to use itertools.zip_longest:

from itertools import zip_longest

x = ["A", "B", "B", "C", "D", "D", "D"]
y = [4, 3, 5, 9, 1, 6, 2]

vals = {}
for vx, vy in zip(x, y):
    vals.setdefault(vx, []).append(vy)

out = dict(zip(vals, map(list, zip(*zip_longest(*vals.values(), fillvalue=0)))))
print(out)

Prints:

{'A': [4, 0, 0], 'B': [3, 5, 0], 'C': [9, 0, 0], 'D': [1, 6, 2]}
Answered By: Andrej Kesely

You have all the building blocks there, but I think you might be attempting to much at once. I would start with three distinct steps:

  1. build the base result
  2. find the length of the longest result
  3. pad each base result to the length of the longest
x = ['A', 'B', 'B', 'C', 'D', 'D', 'D']
y = [ 4 ,  3 ,  5 ,  9 ,  1 ,  6 ,  2 ]

results = {}
for key, value in zip(x, y):
    results.setdefault(key, []).append(value)

longest_value = max(len(value) for value in results.values())

for value in results.values():
    value.extend([0] * (longest_value - len(value)))

print(results)

That should give you:

{'A': [4, 0, 0], 'B': [3, 5, 0], 'C': [9, 0, 0], 'D': [1, 6, 2]}
Answered By: JonSG
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.