Как поменять местами единицы и нули в двоичном представлении числа без перебора значений?
я пробовал подобный код:
s = '01110'
s2 = ''
for i in s: # перебор всех значений
if i == '1':
s2 += '0'
else:
s2 += '1'
print(s)
но так как подобный код будет работать достаточно долго на подобных строках с большей длинной, данный способ не подходит
Ответы (2 шт):
Вариант решения без цикла:
res = bin(2**len(s) - 1 - int(s, 2))[2:]
Простой и быстрый вариант решения, используя работу со строками:
res = s.replace("1", "2").replace("0", "1").replace("2", "0")
Вообще есть нативные питоновские функции для таких преобразований строк:
t = str.maketrans('01', '10')
print('01110'.translate(t))
Вывод:
10001
maketrans просто создаёт словарь, переводящий соответствующие символы одной строки в символы другой строки, там по сути коды символов внутри. Вот что находится в t:
{48: 49, 49: 48}
48 - это код символа 0, а 49 - код символа 1.
Работает это в общем-то довольно быстро:
%%time
s = '01110' * 100_000
s1 = s.translate(t)
Вывод:
CPU times: user 1.08 ms, sys: 0 ns, total: 1.08 ms
Wall time: 1.09 ms
Хотя оба варианта от MaxU на той же строке работают в 100 раз быстрее, если что, порядка 8 µs.
P.S. Ваш код работает долго из-за того, что вы плюсуете строки на каждом шагу цикла, при этом каждый раз создаётся новая строка всё большей длины. Такого метода однозначно нужно избегать в первую очередь.