import itertools

@register.filter
def zip_longest(list_a, list_b, *args):
    """
    function to combine the dual lists
    :param `list_a` is list A.
    :param `list_b` is list B.
    :param `*args` is optional arguments.

    as one zip_longest method (with None value), eg:

    >>> list_a = [1, 2, 3]
    >>> list_b = [1]
    >>>
    >>> list(zip_longest(list_a, list_b))
    [
      [1, 2, 3]
      [1, None, None]
    ]
    >>> # OR more than 2 arguments
    >>> list(zip_longest(list_a, list_b, [21, 22]))
    [
      (1, 1, 21),
      (2, None, 22),
      (3, None, None)
    ]
    """
    return itertools.zip_longest(list_a, list_b, *args)


@register.filter
def add_more_zip(zip_longest, list_c):
    """
    function to add more list into zipped longest.
    eg:
    [
      ('saya', 1, 'xxx'),
      (None, 3, '33333')
    ]

    {% for a, b, c in list_a|zip_longest:list_b|add_more_zip:list_c %}
        {{ a }} {{ b }} {{ c }}
    {% endfor %}
    """
    zipped_list = list(zip_longest)
    zipped_list_out = []
    tmp_length = 0

    for tuple_1, value in itertools.zip_longest(zipped_list, list_c):
        if tuple_1 is not None:
            new_tuples = tuple_1.__add__((value,))
            tmp_length = len(tuple_1)
        else:
            tuple_1 = (None,) * tmp_length
            new_tuples = tuple_1.__add__((value,))
        zipped_list_out.append(new_tuples)

    return zipped_list_out