简体   繁体   中英

Python 3.x: Transform string

I need to transform source string into extended string, eg: A1f4h3L2 => AffffhhhLL

My code:

source = []
answer = ''
s1 = 'S15Y16r13g11b8X8J15Q9V2i18p5e10'
source += s1
i = 0
while i <= (len(source)-1):
    if source[i].isalpha:
        if source[i+1].isdigit:
            if source[i+2].isdigit:
                answer += (str(source[i]) * int(source[i+1] + source[i+2]))
                i += 2
            else:
                answer += (str(source[i]) * int(source[i+1]))
                i += 1
            i+=1

It works till "8X". Exception with: ValueError: invalid literal for int() with base 10: '8X'

Link to pytontutor.com visualisation

I can't understand why code works till i == 12

you can do it in pythonic way:

>>> a="A1f4h3L2"
>>> "".join(map(lambda x,y:x*int(y),a[::2],a[1::2]))
'AffffhhhLL'

how it works:

>>> a[::2]            # give me all alpahbhet
'AfhL'   
>>> a[1::2]           # gives me all integer
'1432'

you can use zip also:

>>> "".join(x*int(y) for x,y in zip(a[::2],a[1::2]))
'AffffhhhLL'

above works for digit less then 10

if digit is greater than 10:

>>> import re
>>> s1 = 'S15Y16r13g11b8X8J15Q9V2i18p5e10'
>>> "".join(x*int(y) for x,y in zip(re.findall('[a-zA-Z]',s1),re.findall('\d+',s1)))      
'SSSSSSSSSSSSSSSYYYYYYYYYYYYYYYYrrrrrrrrrrrrrgggggggggggbbbbbbbbXXXXXXXXJJJJJJJJJJJJJJJQQQQQQQQQVViiiiiiiiiiiiiiiiiipppppeeeeeeeeee'

using lambda and map:

>>> "".join(map(lambda x,y:x*int(y),re.findall('[a-zA-Z]',s1),re.findall('\d+',s1)))     
'SSSSSSSSSSSSSSSYYYYYYYYYYYYYYYYrrrrrrrrrrrrrgggggggggggbbbbbbbbXXXXXXXXJJJJJJJJJJJJJJJQQQQQQQQQVViiiiiiiiiiiiiiiiiipppppeeeeeeeeee'

check this if you dont want to use re:

>>> s1 = 'S15Y16r13g11b8X8J15Q9V2i18p5e10'
>>> my_list =[]
>>> my_digit =''
>>> for x in s1:
...     if x.isalpha():
...         if my_digit != '':
...             my_list.append(my_digit)
...             my_digit=''
...         my_list.append(x)
...     else:
...         my_digit += x
... 
>>> my_list
['S', '15', 'Y', '16', 'r', '13', 'g', '11', 'b', '8', 'X', '8', 'J', '15', 'Q', '9', 'V', '2', 'i', '18', 'p', '5', 'e']

now you can apply any methods from above like this:

>>> "".join(x*int(y) for x,y in zip(my_list[::2],my_list[1::2]))

I'd first convert this string:

A = 'S15Y16r13g11b8X8J15Q9V2i18p5e10'

to this list:

B = ['S', '15', 'Y', '16', 'r', '13', 'g', '11', 'b', '8', 'X', '8', 'J', '15', 'Q', '9', 'V', '2', 'i', '18', 'p', '5', 'e', '10']

Converting from A to B can be done by cutting the string in pieces:

A = 'S15Y16r13g11b8X8J15Q9V2i18p5e10'
B = []
start = 0
while start < len(A):
  i = start
  while A[i].isalpha():
    i = i + 1
  k = i
  while k < len(A) and A[k].isdigit():
    k = k + 1
  B.append(A[start:i])
  B.append(A[i:k])
  start = k

Now is way easier to produce your desired string:

>>> ''.join([(B[i] * int(B[i+1])) for i in range(0, len(B), 2)])
'SSSSSSSSSSSSSSSYYYYYYYYYYYYYYYYrrrrrrrrrrrrrgggggggggggbbbbbbbbXXXXXXXXJJJJJJJJJJJJJJJQQQQQQQQQVViiiiiiiiiiiiiiiiiipppppeeeeeeeeee'

Your specification was not overly detailed, but you can easily change the regexps to match your exact requirements

>>> def expand(s):
...     from re import findall
...     return "".join([c*int(n) for c, n in zip( findall(r'[A-Za-z]+',s),
...                                               findall(r'[0-9]+',   s))])
...
>>> print(expand(('S15Y16r13g11b8X8J15Q9V2i18p5e10'))
SSSSSSSSSSSSSSSYYYYYYYYYYYYYYYYrrrrrrrrrrrrrgggggggggggbbbbbbbbXXXXXXXXJJJJJJJJJJJJJJJQQQQQQQQQVViiiiiiiiiiiiiiiiiipppppeeeeeeeeee
>>> 

No re

def expand(s):

    non_d = [] ; d = [] ; current_digit = ""
    for c in s:
        if c.isdigit(): current_digit = current_digit+c
        else:
            non_d.append(c)
            if current_digit: d.append(current_digit)
            current_digit = ""
    d.append(current_digit)
    return("".join(c*int(n) for c,n in zip(non_d, d)))

s = 'S15Y16r13g11b8X8J15Q9V2i18p5e10'
print expand(s)

Output

SSSSSSSSSSSSSSSYYYYYYYYYYYYYYYYrrrrrrrrrrrrrgggggggggggbbbbbbbbXXXXXXXXJJJJJJJJJJJJJJJQQQQQQQQQVViiiiiiiiiiiiiiiiiipppppeeeeeeeeee

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM