Добавление строк в списки вместе - PullRequest
12 голосов
/ 28 мая 2019

Я хочу преобразовать список ["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' не может быть интерпретированкак целое число

Любая помощь приветствуется.

Редактировать: Спасибо, ребята, все ваши решения работали отлично:)

Ответы [ 4 ]

13 голосов
/ 28 мая 2019

Лучшее решение, используя zip, самое умное:

>>> l = ["A","B","A","A","B"]
>>> [x + y for x, y in zip(l, l[1:])]
['AB', 'BA', 'AA', 'AB']
>>> 

Или используйте этот список понимания:

>>> l = ["A","B","A","A","B"]
>>> [v + l[i + 1] for i, v in enumerate(l[:-1])]
['AB', 'BA', 'AA', 'AB']
>>> 
12 голосов
/ 28 мая 2019

Использование zip():

>>> lst = ["A","B","A","A","B"]
>>> [x + y for x, y in zip(lst, lst[1:])]
['AB', 'BA', 'AA', 'AB']
6 голосов
/ 28 мая 2019

Вы можете использовать map():

s = list(map(str.__add__, lst[:-1], lst[1:]))

Чуть лучше использовать operator.concat() (спасибо за совет, @MykolaZotko):

import operator

s = list(map(operator.concat, lst[:-1], lst[1:]))

Upd.

Я решил провести несколько тестов для больших данных.

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))

Результаты:

  1. Python 2:

    10.447159509
    11.529946446
    20.962497298000002
    20.515838672
    
  2. Python 3:

    10.370675522
    11.429417197
    20.836504865999995
    20.422865353
    

Для больших данных map() немного (~ 9%) быстрее, но между test1() и test2()

нет существенной разницы
3 голосов
/ 28 мая 2019

В исходном коде есть несколько проблем:

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])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...