Эффективно объединить две строки из кортежей в списке? - PullRequest
0 голосов
/ 01 марта 2019

Я хочу объединить два строковых элемента в списке кортежей

У меня есть это:

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"]

1 Ответ

0 голосов
/ 01 марта 2019

Используйте понимание списка, и только для двух элементов я бы использовал распаковку и объединение кортежей:

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

Другой вариант - использование строкового литерала в формате :

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()каждый раз в цикле смотрите В чем преимущество понимания списка по сравнению с циклом for?

Форматированные строковые литералы, представленные в Python 3.6, и они легко являются самым быстрым способом составления строкс интерполированными элементами (хотя они не запускались таким образом ).

Я также опробовал [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

Это улучшается с большим количеством элементов;на 1 миллион элементов map(starmap(add, largelist)) выигрывает с небольшим отрывом (133ms против 140ms для понимания списка с конкатенацией).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...