代码之家  ›  专栏  ›  技术社区  ›  pyeR_biz

用字符串列表替换字符串元素(使用其索引)

  •  3
  • pyeR_biz  · 技术社区  · 6 年前

    我必须构建的函数是用(数字值*下一个字符)替换字符串中的数字。

    所以, foo = '2 hs4q q2w2 ' 将成为 ' hsqqqq qww ' (注意空间)

    假设 -数字不能为零。

    我提取了数字和下一个字符的(索引、值)。使用该信息获取需要放回字符串中的子字符串:

    foo = '2 hs4q q2w2 '
    
    parameters=[(int(foo_list[b]),b+1) for b in range(len(foo_list)) if foo_list[b].isdigit()]
    parameters # list of tuples (digit,charindex to be extended)
    #[(2, 1), (4, 5), (2, 9), (2, 11)]
    
    for p,i in parameters:
        hoo=p*foo[i]
        print (hoo,type(hoo))
    
     #Out
       <class 'str'> # Two spaces
    qqqq <class 'str'>
    ww <class 'str'>
       <class 'str'> # Two spaces
    

    如何在使用类似字符串的循环中使用所有这些信息?我知道字符串是不可变的,因此必须为每个插入/替换创建一个新的str对象。另外,索引值随着循环的运行而变化。

    解决方案后的注释-

    感谢大家提供四种不同的解决方案,以下是未使用的参考资料 yield from, yield - In practice, what are the main uses for the new “yield from” syntax in Python 3.3?

    5 回复  |  直到 6 年前
        1
  •  3
  •   Olivier Melançon iacob    6 年前

    单位数

    您可以检查字符是否为数字, str.isdigit ,如果是,则将其强制转换为 int 再乘以下一个字符。这个逻辑可以写为一个给定的生成器 str.join .

    代码

    def expand_string(s):
        return ''.join([(int(c) - 1) * s[i+1] if c.isdigit() else c for i, c in enumerate(s)])
    

    例子

    foo = '2 hs4q q2w2 '
    print(expand_string(foo)) # '  hsqqqq qww  '
    

    但是,对于具有多个数字的字符串(如 f10o' .

    多位数

    如果还想考虑具有多个数字的数字,可以编写一个生成器函数,该函数使用 itertools.groupby .

    代码

    from itertools import groupby
    
    def group_digits(s):
        for isdigit, group in groupby(s, str.isdigit):
            yield from [''.join(group)] if isdigit else group
    
    def expand_string(s):
        s = list(group_digits(s))
        return ''.join((int(c) - 1) * s[i+1] if c.isdigit() else c for i, c in enumerate(s))
    

    例子

    foo = 'f10o'
    print(expand_string(foo)) # 'foooooooooo'
    
        2
  •  3
  •   Ajax1234    6 年前

    你可以用 re.sub :

    import re
    foo = '2 hs4q q2w2 '
    new_foo = re.sub('\d+[\w\W]{1}', lambda x:x.group()[-1]*int(x.group()[:-1]), foo)
    

    输出:

    '  hsqqqq qww  '
    
        3
  •  1
  •   jpp    6 年前

    一种方法是使用 zip (或) itertools.zip_longest )根据字符是否为数字,生成一个项目。

    from itertools import zip_longest, islice
    
    foo = '2 hs4q q2w2 '
    
    def gen(x):
        for i, j in zip_longest(x, islice(x, 1, None), fillvalue=''):
            if i.isdigit():
                yield j * (int(i)-1)
            else:
                yield i
    
    res = ''.join(list(gen(foo)))
    
    # '  hsqqqq qww  '
    
        4
  •  1
  •   Aaditya Ura    6 年前

    在当前迭代中使用下一个索引时要小心,因为如果字符串类似于foo='2 hs4q q2w2 2' 使用Try和Except

    foo = '2 hs4q q2w2 '
    
    splitted_data=list(foo)
    
    for i,j in enumerate(splitted_data):
        try:
            if j.isdigit():
                splitted_data[i]=splitted_data[i+1]*int(j)
        except IndexError:
            pass
    
    print("".join(splitted_data))
    

    输出:

       hsqqqqq qwww   
    
        5
  •  0
  •   Artur Amorim    6 年前

    这种函数可以通过while循环获得:

    def new_string(string):
        # Create the variable new_string
        new_string = ""
        i = 0
        while i < len(string):
            char = string[i]
            # If char is a digit we multiply the next char by it
            if char.isdigit():
                new_string += int(char)*string[i+1]
                i += 2
            # If not we just concatenate char
            else:
                new_string += char
                i += 1
        return new_string
    

    希望有帮助。