ToB*_*ced 10 python-3.x python-3.3
在Python 3中连接序列的首选方法是什么?
现在,我正在做:
import functools
import operator
def concatenate(sequences):
return functools.reduce(operator.add, sequences)
print(concatenate([['spam', 'eggs'], ['ham']]))
# ['spam', 'eggs', 'ham']
Run Code Online (Sandbox Code Playgroud)
需要导入两个单独的模块才能做到这一点似乎很笨拙.
另一种选择可能是:
def concatenate(sequences):
concatenated_sequence = []
for sequence in sequences:
concatenated_sequence += sequence
return concatenated_sequence
Run Code Online (Sandbox Code Playgroud)
但是,这是不正确的,因为您不知道序列是列表.
你可以这样做:
import copy
def concatenate(sequences):
head, *tail = sequences
concatenated_sequence = copy.copy(head)
for sequence in sequences:
concatenated_sequence += sequence
return concatenated_sequence
Run Code Online (Sandbox Code Playgroud)
但这似乎很容易出错 - 直接调用复制?(我知道head.copy()列表和元组的作用,但copy不是序列ABC的一部分,所以你不能依赖它......如果你得到了字符串怎么办?).你必须复制以防止变异,以防你被交给a MutableSequence.此外,此解决方案会强制您首先解压缩整个序列集.再试一次:
import copy
def concatenate(sequences):
iterable = iter(sequences)
head = next(iterable)
concatenated_sequence = copy.copy(head)
for sequence in iterable:
concatenated_sequence += sequence
return concatenated_sequence
Run Code Online (Sandbox Code Playgroud)
但是来吧......这是蟒蛇!那么......这样做的首选方法是什么?
我会itertools.chain.from_iterable()改用:
import itertools
def chained(sequences):
return itertools.chain.from_iterable(sequences):
Run Code Online (Sandbox Code Playgroud)
或者,因为你用python-3.3标记了这个,你可以使用新的yield from语法(看看ma,没有导入!):
def chained(sequences):
for seq in sequences:
yield from seq
Run Code Online (Sandbox Code Playgroud)
它们都返回迭代器(list()如果必须实现完整列表,则使用它们).大多数情况下,您不需要一系列连接序列,实际上,您只需要循环它们来处理和/或搜索某些内容.
请注意,对于字符串,您应该使用str.join()而不是我的答案或您的问题中描述的任何技术:
concatenated = ''.join(sequence_of_strings)
Run Code Online (Sandbox Code Playgroud)
结合起来,为了快速准确地处理序列,我会使用:
def chained(sequences):
for seq in sequences:
yield from seq
def concatenate(sequences):
sequences = iter(sequences)
first = next(sequences)
if hasattr(first, 'join'):
return first + ''.join(sequences)
return first + type(first)(chained(sequences))
Run Code Online (Sandbox Code Playgroud)
这适用于元组,列表和字符串:
>>> concatenate(['abcd', 'efgh', 'ijkl'])
'abcdefghijkl'
>>> concatenate([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
[1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> concatenate([(1, 2, 3), (4, 5, 6), (7, 8, 9)])
(1, 2, 3, 4, 5, 6, 7, 8, 9)
Run Code Online (Sandbox Code Playgroud)
并使用更快''.join()的字符串序列.