Я хочу преобразовать список ["A","B","A","A","B"]
в список ["AB","BA","AA","AB"]
.
Я попытался определить новый список, в котором первый элемент удален, а затем добавить строки списков вместе. После чего я планирую удалить последний элемент нового списка, чтобы получить результат.
lista = sequences
lista.pop(0)
print(lista)
for x in range(sequences):
mc =sequences[x]+lista[x]
Но все, что я получаю, это
TypeError: 'list' object cannot be interpreted as an integer
Любая помощь приветствуется.
Редактировать: Спасибо, ребята, все ваши решения сработали отлично :)
Лучшее решение, используя zip
с пониманием списка, самое умное:
>>> l = ["A","B","A","A","B"]
>>> [x + y for x, y in zip(l, l[1:])]
['AB', 'BA', 'AA', 'AB']
>>>
Или используйте enumerate
с пониманием списка:
>>> l = ["A","B","A","A","B"]
>>> [v + l[i + 1] for i, v in enumerate(l[:-1])]
['AB', 'BA', 'AA', 'AB']
>>>
Используйте zip()
:
>>> lst = ["A","B","A","A","B"]
>>> [x + y for x, y in zip(lst, lst[1:])]
['AB', 'BA', 'AA', 'AB']
s = list(map(str.__add__, lst[:-1], lst[1:]))
Немного лучше использовать operator.concat()
(спасибо за совет, @MykolaZotko):
import operator
s = list(map(operator.concat, lst[:-1], lst[1:]))
Обновление
Я решил провести несколько тестов на больших данных.
import operator
lst = [...] # list with 10000 random uppercase letters
def test1():
return list(map(operator.concat, lst[:-1], lst[1:]))
def test2():
return [x + y for x, y in zip(lst, lst[1:])]
def test3():
return [v + lst[i + 1] for i, v in enumerate(lst[:-1])]
def test4():
s = ''.join(lst)
return [s[i:i + 2] for i in range(len(s) - 1)]
if __name__ == '__main__':
import timeit
print(timeit.timeit("test1()", setup = "from __main__ import test1, lst", number=10000))
print(timeit.timeit("test2()", setup = "from __main__ import test2, lst", number=10000))
print(timeit.timeit("test3()", setup = "from __main__ import test3, lst", number=10000))
print(timeit.timeit("test4()", setup = "from __main__ import test4, lst", number=10000))
Результаты:
Питон 2:
10.447159509
11.529946446
20.962497298000002
20.515838672
Питон 3:
10.370675522
11.429417197
20.836504865999995
20.422865353
На больших данных map()
немного (~9%) быстрее, но существенной разницы между test1()
и test2()
нет.
@MykolaZotko, это не быстрее, на несколько миллисекунд медленнее, почти то же самое. Я сделал ошибку при копировании данных
В исходном коде есть несколько проблем:
sequences = ["A","B","A","A","B"]
lista = sequences
lista.pop(0)
print(lista)
for x in range(sequences):
mc =sequences[x]+lista[x]
Во-первых, оператор lista = sequences
не копирует последовательности. Вместо этого lista
и sequences
становятся двумя разными именами для одного и того же списка. То, что вы делаете, используя одно имя, происходит и с другим. lista.pop(0)
то же, что sequences.pop(0)
. Если вам нужна копия, импортируйте библиотеку copy
.
import copy
sequences = ["A","B","A","A","B"]
lista = copy.copy(sequences)
lista.pop(0)
print(lista)
for x in range(sequences):
mc =sequences[x]+lista[x]
Во-вторых, ваше утверждение range(sequences)
неверно. Функция range()
принимает в качестве входных данных целые числа, а не списки. Вот что тебе дал TypeError: 'list' object cannot be interpreted as an integer
# VALID
range(5)
range(3)
range(10)
# INVALID
range(["A","B","A"])
range(["eyes", "nose", "tail"])
sequences
— это список. Вы хотите range(len(sequences))
нетrange(sequences)
В конце концов, мы можем изменить ваш исходный код, чтобы он работал:
import copy
sequences = ["A","B","A","A","B"]
lista = copy.copy(sequences)
lista.pop(0)
print(lista) # prints ["B","A","A","B"]
mc = list()
for x in range(len(lista)):
mc.append(lista[x] + sequences[x + 1])
Вы также можете использовать
operator.add
илиoperator.concat
. Странно, чтоmap
быстрее. Обычноmap
работает медленнее, чем listcomp.