Duplicate the elements of a list a given number of times
按指定次数重复列表中的元素。按例还是先写测试用例:
这个问题可以分两步来解,先将列表的每个元素都转换成列表,列表表包含指定个数重复的原元素,然后再把所有列表拼接成一维列表即为结果。为简洁及逼格,可以套用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]
。
代码实现:
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
接受两个参数,第一个应与initial
和reduce
返回值同类型,第二个是sequence
里的元素。
本例中,initial
是空列表[]
。sequence
的每个元素都是包含两个相同元素的列表。function
接受的两个参数都是无嵌套的列表,并将它们拼接成一个无嵌套的列表。