Как объединить последующие цифры в списке Python в двузначное (или более) число

У меня есть следующая строка:

string = 'TAA15=ATT'

Я составляю список из этого:

string_list = list(string)
print(string_list)

и результат:

['T', 'A', 'A', '1', '5','=', 'A', 'T', 'T']

Мне нужно определить последующие цифры и объединить их в одно число, как показано ниже:

['T', 'A', 'A', '15','=', 'A', 'T', 'T']

Я также очень обеспокоен выступлениями. Это преобразование строки выполняется тысячу раз.

Спасибо за любые подсказки, которые вы можете предоставить.

Ваша задача состоит в том, чтобы объединить последовательные цифры в списке строк или вашей реальной задачей является извлечение последовательных цифр из строки? А по поводу «составляю из этого список»: «Куда делись =

MisterMiyagi 10.07.2019 12:47

@MisterMiyagi: объединить последовательные цифры. Забыл написать, что удаляю '=' в строке перед составлением списка. Спасибо

user123892 10.07.2019 13:03

Вы хотите знак равенства или нет? В своем вопросе вы этого не говорите, но вы приняли ответ с ним. = всегда после цифр?

Francesco Boi 10.07.2019 13:18

Знак равенства не имеет значения для моего вопроса. Я не хочу создавать путаницу, так как я принял ответ со знаком «=», поэтому я отредактировал вопрос, вернув «=» в string_list. Извините за мою ошибку.

user123892 10.07.2019 18:15
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
2
4
166
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

Использование itertools.groupby

Бывший:

from itertools import groupby
string = 'TAA15=ATT'

result = []
for k, v in groupby(string, str.isdigit):
    if k:
        result.append("".join(v))
    else:
        result.extend(v)
print(result)

Выход:

['T', 'A', 'A', '15', '=', 'A', 'T', 'T']

Очень хорошо. Но было достаточно и эффективнее сказать: else: result.extend(v) (список создавать не нужно).

Booboo 10.07.2019 13:10

Вместо lambda x: x.isdigit() используйте str.isdigit

Jab 10.07.2019 13:23

Вы можете использовать регулярные выражения, в Python библиотека re:

import re
string = 'TAA15=ATT'
num = re.sub('[^0-9,]', "", string)
pos = string.find(num)
str2 = re.sub('\\d+',"", string)
str2 = re.sub('=',"", str2)
print(str2)
l = list()
for el in str2:
    l.append(el)
l.insert(pos, num)
print(l)

По сути, re.sub('[^0-9,]', "", string) говорит: возьмите строку, сопоставьте все символы, которые не являются (^ означает отрицание) числами (0-9), и замените их вторым параметром, т. е. пустой строкой. Так что в основном остаются только цифры, которые вы должны преобразовать в целое число.

Если = всегда после цифры вместо

str2 = re.sub('\\d+',"", string)
str2 = re.sub('=',"", str2)

ты можешь сделать

str2 = re.sub('\\d+=',"", string)

Мне нужно обнаружить двузначные числа в списке, но также изменить список с помощью [.., '1', '5', ..], чтобы получить [.., '15', ..]

user123892 10.07.2019 12:56

Я изменил код в ответе: теперь он должен работать

Francesco Boi 10.07.2019 13:14
Ответ принят как подходящий

Вот очень короткое решение

import re

def digitsMerger(source):
    return re.findall(r'\d+|.', source)
digitsMerger('TAA15=ATT')
['T', 'A', 'A', '15', '=', 'A', 'T', 'T']

FWIW, на моем рабочем столе это решение занимает примерно на 1/3 меньше времени, чем решение с использованием itertools.groupby.

Booboo 10.07.2019 13:27

Очень мило, но можешь объяснить? Я имею в виду, соответствует ли он последовательности цифр (которые складываются вместе) ИЛИ любому другому символу?

Francesco Boi 10.07.2019 13:40

Регулярное выражение начинает с поиска цифры, и если оно найдено, оно пытается получить как можно больше цифр. Если он не находит ни одной цифры, он просто берет 1 символ (. является самым большим подстановочным знаком, \D также сработало бы, чтобы означать «что угодно, кроме цифры»)

Shizzen83 10.07.2019 14:12

Другое регулярное выражение:

import re

s = 'TAA15=ATT'

pattern = r'\d+|\D'

m = re.findall(pattern, s)

print(m)

Я не знаю, можно ли это описать как проблему с SO или нет (это явно не проблема для ОП, который задал вопрос), но второй вопрос публикуется, часто есть несколько человек, готовых прыгнуть на него. Итак, вы усердно работаете, чтобы придумать решение, но обнаруживаете, что кто-то придумал то же самое за пару минут до вас. Или какой-то судья сочтет вопрос слишком похожим на уже заданный вопрос и ответ на него, и вы даже не сможете опубликовать свою работу. Теперь я не утруждаюсь отвечать на новые вопросы, если только они не остались без ответа какое-то время.

Booboo 10.07.2019 13:38

@RonaldAaronson хорошая мысль, я понимаю ваше беспокойство. Я только что попробовал ответы, которые быстрее вписываются в мой код, принятый ответ короткий и быстрый. Как только я получил то, что мне было нужно, я не пробовал другие, это несправедливо, я понимаю.

user123892 10.07.2019 18:24

@RonaldAaronson Я знаю вашу точку зрения, да, на SO есть 3 типа Q. 1-й: значения (~ 20%). 2-й хорошо определен, но не настоящая проблема, как эта (~ 50%) 3-й: настоящие проблемы, которые в большинстве случаев остаются без ответа... Каким-то образом SO должен отфильтровать эту проблему. Есть ли какая-нибудь мета-нить, в которой обсуждается этот вопрос?

betontalpfa 11.07.2019 10:38

Вы можете создать функцию, которая сравнивает последнее увиденное значение и следующее, и использовать functools.reduce:

from functools import reduce

string_list = ['T', 'A', 'A', '1', '5', 'A', 'T', 'T']

def combine_nums(lst, nxt):
    if lst and all(map(str.isdigit, (lst[-1], nxt))):
        nxt = lst[-1] + nxt
    return lst + [nxt]

print(reduce(combine_nums, string_list, [])

Результаты:

['T', 'A', 'A', '1', '15', 'A', 'T', 'T']

Другие вопросы по теме