Python функция, которая чередует произвольное количество списков в качестве параметров - PullRequest
0 голосов
/ 18 января 2020

Отредактировано ради простоты, так как я указал, что проблема указывает на «распаковку аргументов».
Я пытаюсь написать функцию, которая чередует произвольное количество списков в качестве параметров. Все списки имеют одинаковую длину. Функция должна возвращать один список, содержащий все элементы из чередующихся входных списков.

def interleave(*args):

    for i, j, k in zip(*args):
        print(f"On {i} it was {j} and the temperature was {k} degrees celsius.")

interleave(["Monday Tuesday Wednesday Thursday Friday Saturday Sunday".split()],["rainy rainy sunny cloudy rainy sunny sunny".split()],[10,12,12,9,9,11,11])

Вывод:

On ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'] it was ['rainy', 'rainy', 'sunny', 'cloudy', 'rainy', 'sunny', 'sunny'] and the temperature was 10 degrees celsius.

желаемый вывод:

On Monday it was rainy and the temperature was 10 degrees celsius.
On Tuesday it was rainy and the temperature was 12 degrees celsius.
On Wednesday it was sunny and the temperature was 12 degrees celsius.
On Thursday it was cloudy and the temperature was 9 degrees celsius.
On Friday it was rainy and the temperature was 9 degrees celsius.
On Saturday it was sunny and the temperature was 11 degrees celsius.
On Sunday it was sunny and the temperature was 11 degrees celsius.

Ответы [ 2 ]

1 голос
/ 18 января 2020

Не включайте результат split в список. Итак, измените

interleave(["Monday Tuesday Wednesday Thursday Friday Saturday Sunday".split()],["rainy rainy sunny cloudy rainy sunny sunny".split()],[10,12,12,9,9,11,11])

на

interleave("Monday Tuesday Wednesday Thursday Friday Saturday Sunday".split(),"rainy rainy sunny cloudy rainy sunny sunny".split(),[10,12,12,9,9,11,11]).

В то время как первое приведет к двум спискам длины 1 и списку длина 7 в качестве аргументов interleave, последнее / изменение приведет к трем спискам длины 7 в качестве аргументов. Последнее - то, что вам нужно, чтобы оператор zip работал так, как вы хотите.

1 голос
/ 18 января 2020

В разделе рецептов документации itertools это называется roundrobin:

def roundrobin(*iterables):
    "roundrobin('ABC', 'D', 'EF') --> A D E B F C"
    # Recipe credited to George Sakkis
    num_active = len(iterables)
    nexts = cycle(iter(it).__next__ for it in iterables)
    while num_active:
        try:
            for next in nexts:
                yield next()
        except StopIteration:
            # Remove the iterator we just exhausted from the cycle.
            num_active -= 1
            nexts = cycle(islice(nexts, num_active))

В частности, для списков (одинакового размера) вы можете упростить это до

def interleave(*args):
    return list(chain.from_iterable(zip(*args)))
...