将任意数量的列表作为参数交错的 Python 函数

Posted

技术标签:

【中文标题】将任意数量的列表作为参数交错的 Python 函数【英文标题】:A Python function that interleaves arbitrary number of lists as parameters 【发布时间】:2020-05-05 04:29:26 【问题描述】:

为简单起见进行了编辑,因为我已将问题指向“参数拆包”。 我正在尝试编写一个将任意数量的列表作为参数交错的函数。所有列表的长度相同。该函数应返回一个列表,其中包含交错的输入列表中的所有元素。

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.

【问题讨论】:

【参考方案1】:

不要将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 运算符按您的意愿工作所需要的。

【讨论】:

【参考方案2】:

itertools 文档中的recipe section 将此称为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)))

【讨论】:

python 的 1 周似乎有点先进。这些函数让人想起 java 的接口。 @Saurus 这些函数让人想起 java 的接口。 哪些函数,如何使用? java中的iterable接口也有next()。上面的例子也使用了迭代器。 @Saurus 好吧,是的。它利用了迭代器协议。 iterables 不限于列表;您可以传递列表、元组、集合、字符串、字典或任何其他实现迭代器协议的组合。

以上是关于将任意数量的列表作为参数交错的 Python 函数的主要内容,如果未能解决你的问题,请参考以下文章

Python ❀ 函数

Python ❀ 函数

Python编程入门到实践 - 笔记( 8 章)

有条件地将任意数量的默认命名参数传递给函数

你能写一个可以接受任意数量参数的 c# 装饰器函数吗?

Python 构造一个可接受任意数量参数的函数