关于字符串:在python列表中串联一个元组的元素

Concatenate elements of a tuple in a list in python

我有一个包含字符串的元组列表
例如:

1
2
3
4
5
6
7
[('this', 'is', 'a', 'foo', 'bar', 'sentences')
('is', 'a', 'foo', 'bar', 'sentences', 'and')
('a', 'foo', 'bar', 'sentences', 'and', 'i')
('foo', 'bar', 'sentences', 'and', 'i', 'want')
('bar', 'sentences', 'and', 'i', 'want', 'to')
('sentences', 'and', 'i', 'want', 'to', 'ngramize')
('and', 'i', 'want', 'to', 'ngramize', 'it')]

现在,我希望将元组中的每个字符串连接起来,以创建一个用空格分隔的字符串列表。
我使用以下方法:

1
2
3
NewData=[]
for grams in sixgrams:
       NewData.append( (''.join([w+' ' for w in grams])).strip())

工作正常。

但是,我有超过一百万个元组的列表。 所以我的问题是这种方法是否足够有效或是否有更好的方法来做到这一点。
谢谢。


对于大量数据,您应该考虑是否需要将所有数据都保留在列表中。如果您一次要处理每个字符串,则可以创建一个生成器,该生成器将产生每个连接的字符串,但不会使它们始终占用内存:

1
new_data = (' '.join(w) for w in sixgrams)

如果您还可以从生成器中获取原始元组,那么也可以避免在内存中使用sixgrams列表。


列表推导会创建临时字符串。只需使用' '.join即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
>>> words_list = [('this', 'is', 'a', 'foo', 'bar', 'sentences'),
...               ('is', 'a', 'foo', 'bar', 'sentences', 'and'),
...               ('a', 'foo', 'bar', 'sentences', 'and', 'i'),
...               ('foo', 'bar', 'sentences', 'and', 'i', 'want'),
...               ('bar', 'sentences', 'and', 'i', 'want', 'to'),
...               ('sentences', 'and', 'i', 'want', 'to', 'ngramize'),
...               ('and', 'i', 'want', 'to', 'ngramize', 'it')]
>>> new_list = []
>>> for words in words_list:
...     new_list.append(' '.join(words)) # <---------------
...
>>> new_list
['this is a foo bar sentences',
 'is a foo bar sentences and',
 'a foo bar sentences and i',
 'foo bar sentences and i want',
 'bar sentences and i want to',
 'sentences and i want to ngramize',
 'and i want to ngramize it']

for循环上方可以表示为以下列表理解:

1
new_list = [' '.join(words) for words in words_list]


您可以像这样高效地执行此操作

1
2
joiner ="".join
print map(joiner, sixgrams)

我们仍然可以使用这样的列表理解来提高性能

1
2
joiner ="".join
print [joiner(words) for words in sixgrams]

性能比较表明,上面列出的列表理解解决方案比其他两个解决方案要快一些。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
from timeit import timeit

joiner ="".join

def mapSolution():
    return map(joiner, sixgrams)

def comprehensionSolution1():
    return ["".join(words) for words in sixgrams]

def comprehensionSolution2():
    return [joiner(words) for words in sixgrams]

print timeit("mapSolution()","from __main__ import joiner, mapSolution, sixgrams")
print timeit("comprehensionSolution1()","from __main__ import sixgrams, comprehensionSolution1, joiner")
print timeit("comprehensionSolution2()","from __main__ import sixgrams, comprehensionSolution2, joiner")

在我的机器上输出

1
2
3
1.5691678524
1.66710209846
1.47555398941

性能提升最有可能是因为这样的事实,我们不必每次都从空字符串创建join函数。

编辑:尽管我们可以像这样改善性能,但是最Python化的方法是使用类似于lvc的答案中的生成器。