Duplicate the elements of a list a given number of times

按指定次数重复列表中的元素。按例还是先写测试用例:

from python99.lists.p115 import duplicate def test_duplicate(): assert duplicate([], 2) == [] assert duplicate([1, 2], 3) == [1, 1, 1, 2, 2, 2] assert duplicate([1, 2, 3, 4, 5], 1) == [1, 2, 3, 4, 5]

这个问题可以分两步来解,先将列表的每个元素都转换成列表,列表表包含指定个数重复的原元素,然后再把所有列表拼接成一维列表即为结果。为简洁及逼格,可以套用MapReduce(对映归纳)范式。MapReduce中的主要概念「Map(对映)」和「Reduce(归纳)」是从函数式程序设计语言借来的。简单来说,一个对映函数就是对列表上每一个元素进行指定的操作,并将结果存储于新的列表中。而归纳操作则是对一个列表的元素进行适当的合併。

本例中,对映是「将每个元素都转换成列表」,而归纳则为「把所有列表拼接成一维列表」。举个例子,给定列表[a, b, c, d],指定重复次数3。首先,将列表中每个元素都转换成由三个重复元素组成的列表[[a, a, a], [b, b, b], [c, c, c], [d, d, d, d]]。然后,把所有列表都拼接成一个一维列表[a, a, a, b, b, b, c, c, c, d, d, d]

代码实现:

# Duplicate the elements of a list a given number of times import functools import operator def duplicate(l, n): return functools.reduce(operator.concat, [[e] * n for e in l], [])

Python内建的List comprehension用一种简洁的方式实现了「Map(对映)」。标准库中的functools则提供了「Reduce(归纳)」的实现。

List comprehension的形式为:

[f(x) for x in l]
  • f 为对映函数,可为普通Python函数,也可为表达式
  • x为局部变量,用以引用每一个元素
  • l输入列表

本例中,f[x] * n,将单个元素转换为包含指定次数重复元素的列表。

functools.reduce的源代码为:

_initial_missing = object()

def reduce(function, sequence, initial=_initial_missing):
    """
    reduce(function, sequence[, initial]) -> value
    Apply a function of two arguments cumulatively to the items of a sequence,
    from left to right, so as to reduce the sequence to a single value.
    For example, reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]) calculates
    ((((1+2)+3)+4)+5).  If initial is present, it is placed before the items
    of the sequence in the calculation, and serves as a default when the
    sequence is empty.
    """

    it = iter(sequence)

    if initial is _initial_missing:
        try:
            value = next(it)
        except StopIteration:
            raise TypeError("reduce() of empty sequence with no initial value") from None
    else:
        value = initial

    for element in it:
        value = function(value, element)

    return value

try:
    from _functools import reduce
except ImportError:
    pass

reduce返回值应与initial同类型。function接受两个参数,第一个应与initialreduce返回值同类型,第二个是sequence里的元素。

本例中,initial是空列表[]sequence的每个元素都是包含两个相同元素的列表。function接受的两个参数都是无嵌套的列表,并将它们拼接成一个无嵌套的列表。

results matching ""

    No results matching ""