【问题标题】:Efficiently concatenate two strings from tuples in a list?有效地连接列表中元组中的两个字符串?
【发布时间】:2019-03-01 11:11:12
【问题描述】:

我想在一个元组列表中连接两个字符串元素

我有这个:

mylist = [('a', 'b'), ('c', 'd'), ('e', 'f'), ('g', 'h')]
myanswer = []

for tup1 in mylist:
   myanswer.append(tup1[0] + tup[1])

它正在工作,但有什么简单的方法可以做到这一点?我的真实列表大约有 1000 项,我认为 for 循环不是最有效的方法。

预期输出:

myanswer = ["ab", "cd", "ef", "gh"]

【问题讨论】:

  • 好吧,您的问题令人困惑。您声称它不工作,然后将其更正为工作代码,并要求一种更有效的方法来做到这一点。您确实希望通过一个实际上是有效 Python 代码的示例来确保您提出的问题正确而清晰

标签: python python-3.x list performance


【解决方案1】:

使用列表推导,对于两个元素,我会使用元组解包和连接:

myanswer = [s1 + s2 for s1, s2 in mylist]

另一种选择是使用formatted string literal

myanswer = [f"{s1}{s2}" for s1, s2 in mylist]

两者都相当快:

>>> from random import choice
>>> from string import ascii_letters
>>> from timeit import Timer
>>> testdata = [(choice(ascii_letters), choice(ascii_letters)) for _ in range(10000)]
>>> count, total = Timer('[f"{s1}{s2}" for s1, s2 in mylist]', 'from __main__ import testdata as mylist').autorange()
>>> print(f"List comp with f-string, 10k elements: {total / count * 1000000:7.2f} microseconds")
List comp with f-string, 10k elements: 1249.37 microseconds
>>> count, total = Timer('[s1 + s2 for s1, s2 in mylist]', 'from __main__ import testdata as mylist').autorange()
>>> print(f"List comp with concatenation, 10k elements: {total / count * 1000000:6.2f} microseconds")
List comp with concatenation, 10k elements: 1061.89 microseconds

连接在这里胜出。

列表推导式无需每次循环查找列表对象及其.append() 方法,请参阅What is the advantage of a list comprehension over a for loop?

在 Python 3.6 中引入的格式化字符串文字,并且很容易成为使用插值元素组合字符串的最快方式(即使它们是 didn't start out that way)。

我还尝试了 [itertools.starmap()] 与 [operator.add()] 和 [str.join()],但这似乎没有竞争力:

>>> count, total = Timer('list(starmap(add, mylist))', 'from __main__ import testdata as mylist; from itertools import starmap; from operator import add').autorange()
>>> print(f"itertools.starmap and operator.add, 10k elements: {total / count * 1000000:6.2f} microseconds")
itertools.starmap and operator.add, 10k elements: 1275.02 microseconds
>>> count, total = Timer('list(starmap(str.join, mylist))', 'from __main__ import testdata as mylist; from itertools import starmap').autorange()
>>> print(f"itertools.starmap and str.join, 10k elements: {total / count * 1000000:6.2f} microseconds")
itertools.starmap and str.join, 10k elements: 1564.79 microseconds

它确实会随着更多元素而改进;通过 100 万个元素,map(starmap(add, largelist)) 以微弱优势获胜(133 毫秒对 140 毫秒的连接列表理解)。

【讨论】:

    猜你喜欢
    • 2017-11-10
    • 1970-01-01
    • 1970-01-01
    • 2019-02-08
    • 1970-01-01
    • 2018-11-14
    • 2019-10-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多