【问题标题】:Replace string elements, using their index, by a list of strings使用字符串列表替换字符串元素,使用它们的索引
【发布时间】:2018-11-05 23:17:10
【问题描述】:

我必须构建的函数旨在将字符串中的数字替换为(数字的值 * 下一个字符)。

所以,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?的任何人的参考

【问题讨论】:

    标签: python string python-3.x substring


    【解决方案1】:

    个位数字

    您可以使用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】:

      你可以使用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】:

        一个想法是使用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】:

          在当前迭代中使用下一个索引时要小心,它可能会给你错误,因为如果字符串类似于 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】:

            这样的函数可以使用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
            

            希望对你有帮助。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2019-06-26
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2021-12-19
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多