之所以有效,是因为加法被重载(在元组上)以返回连接的元组:
>>> () + ('hello',) + ('these', 'are') + ('my', 'tuples!')
('hello', 'these', 'are', 'my', 'tuples!')
这基本上就是sum 正在做的事情,你给一个空元组的初始值,然后将元组添加到它。
但是这通常是一个坏主意,因为添加元组会创建一个新元组,因此您创建几个中间元组只是为了将它们复制到连接的元组中:
()
('hello',)
('hello', 'these', 'are')
('hello', 'these', 'are', 'my', 'tuples!')
这是一个具有二次运行时行为的实现。通过避免中间元组可以避免这种二次运行时行为。
>>> tuples = (('hello',), ('these', 'are'), ('my', 'tuples!'))
使用嵌套生成器表达式:
>>> tuple(tuple_item for tup in tuples for tuple_item in tup)
('hello', 'these', 'are', 'my', 'tuples!')
或者使用生成器函数:
def flatten(it):
for seq in it:
for item in seq:
yield item
>>> tuple(flatten(tuples))
('hello', 'these', 'are', 'my', 'tuples!')
或者使用itertools.chain.from_iterable:
>>> import itertools
>>> tuple(itertools.chain.from_iterable(tuples))
('hello', 'these', 'are', 'my', 'tuples!')
如果您对它们的性能感兴趣(使用我的simple_benchmark package):
import itertools
import simple_benchmark
def flatten(it):
for seq in it:
for item in seq:
yield item
def sum_approach(tuples):
return sum(tuples, ())
def generator_expression_approach(tuples):
return tuple(tuple_item for tup in tuples for tuple_item in tup)
def generator_function_approach(tuples):
return tuple(flatten(tuples))
def itertools_approach(tuples):
return tuple(itertools.chain.from_iterable(tuples))
funcs = [sum_approach, generator_expression_approach, generator_function_approach, itertools_approach]
arguments = {(2**i): tuple((1,) for i in range(1, 2**i)) for i in range(1, 13)}
b = simple_benchmark.benchmark(funcs, arguments, argument_name='number of tuples to concatenate')
b.plot()
(Python 3.7.2 64 位,Windows 10 64 位)
因此,虽然sum 方法在您仅连接几个元组时非常快,但如果您尝试连接大量元组,则会非常慢。许多元组的测试方法中最快的是itertools.chain.from_iterable