【问题标题】:Is there an elegant and concise syntax to do this in Python?在 Python 中是否有一种优雅而简洁的语法来做到这一点?
【发布时间】:2014-02-20 05:13:57
【问题描述】:

基本上我有一个这样的字符串:

"1,2,3 2,3,4 3,4,5 4,5,6 5,6,7 26,117,1212"

我想用空格分割它,然后替换每个元素中的每个第 i 个元素。因此,如果我用 0 替换每个第二个元素,那么结果将是:

"1,0,3 2,0,4 3,0,5 4,0,6 5,0,7 26,0,1212"

我是否应该只拆分它,然后对于每个字符串元素,将它们拆分在一个 for 循环中,然后如果我在指定的索引处,则使用指定的值,否则元素本身,然后将其附加到最终字符串?

我认为在 Python 中可能有更好/更快和更短的方法来做同样的事情。

【问题讨论】:

    标签: python string parsing


    【解决方案1】:
    nums = [[int(num) for num in substring.split(',')] for substring in s.split()]
    for row in nums:
        row[1] = 0
    

    第一行将输入从文本格式转换为数字列表列表,第二行和第三行替换每个子列表中的第二项。此时,如果您需要打印数字或将它们写入文件或其他内容,您可以转换回字符串,但如果您需要继续处理数字,最好继续使用nums列表。

    如果您要立即将数据转回字符串,则不值得调用int。在这种情况下,代码简化为

    nums = [substring.split(',') for substring in s.split()]
    for row in nums:
        row[1] = '0'
    

    然后再转回字符串,

    string_representation = ' '.join(','.join(row) for row in nums)
    

    要替换每个部分的第一个或第三个元素,只需将row[1] = '0' 中的1 替换为您要替换的索引即可。 0 用于第一个元素,2 用于第三个元素。您可以制作一个函数来获取您要使用的索引:

    def zero_out_column(s, index):
        nums = [substring.split(',') for substring in s.split()]
        for row in nums:
            row[index] = '0'
        return ' '.join(','.join(row) for row in nums)
    

    【讨论】:

    • 谢谢,我会将所有内容转换回字符串,因为这是应用程序使用的内容。
    • @JoanVenge:根据你所说的“这就是应用程序使用的东西”的意思,无论如何保留nums 列表可能是值得的。
    • 对不起,我的意思是我正在编写此脚本的应用程序,该脚本将通过按钮调用,因此在代码执行后我无法将任何内容保存在内存中,并进行了操作。但最后我只是更新程序中的一个参数字段,在这种情况下是一个字符串,这就是我说的原因:)
    【解决方案2】:

    使用numpy.matrix:

    >>> import numpy as np
    >>>
    >>> s = "1,2,3 2,3,4 3,4,5 4,5,6 5,6,7 26,117,1212"
    >>> m = np.matrix(s.replace(' ', ';').replace(',', ' '), dtype=str)
    >>> m[:, 1] = '0'
    >>> ' '.join(map(','.join, np.asarray(m)))
    '1,0,3 2,0,4 3,0,5 4,0,6 5,0,7 26,0,1212'
    

    【讨论】:

      【解决方案3】:

      这是一个正则表达式版本:

      import re
      a = "1,2,3 2,3,4 3,4,5 4,5,6 5,6,7 26,117,1212"
      
      for i in range(3):
          print re.sub(r"((^| )(\d+,){%d})(\d+)" % i, r"\g<1>0", a)
      

      输出:

      0,2,3 0,3,4 0,4,5 0,5,6 0,6,7 0,117,1212
      1,0,3 2,0,4 3,0,5 4,0,6 5,0,7 26,0,1212
      1,2,0 2,3,0 3,4,0 4,5,0 5,6,0 26,117,0
      

      【讨论】:

      • 非常好!你能解释一下repl字符串r"\g&lt;1&gt;0"是如何解析给定pattern的吗?
      【解决方案4】:

      我不确定你的最终目标是什么,但 numpy 擅长操纵数字矩形以获得乐趣和利润。

      > import numpy as np; from StringIO import StringIO
      > s = "1,2,3 2,3,4 3,4,5 4,5,6 5,6,7 26,117,1212"
      > a = np.loadtxt(StringIO(s.replace(' ', '\n')), delimiter=',', dtype=int)
      > a # ah, much better
      array([[   1,    2,    3],
             [   2,    3,    4],
             [   3,    4,    5],
             [   4,    5,    6],
             [   5,    6,    7],
             [  26,  117, 1212]])
      > a[:, 1] = 0 # all the rows, column 1
      > a
      array([[   1,    0,    3],
             [   2,    0,    4],
             [   3,    0,    5],
             [   4,    0,    6],
             [   5,    0,    7],
             [  26,    0, 1212]])
      > (' '.join(['%s,%s,%s'] * len(a))) % tuple(a.flatten()) # okay, apply silly formatting
      '1,0,3 2,0,4 3,0,5 4,0,6 5,0,7 26,0,1212'
      

      【讨论】:

      • 相比eval,最好将numpy.loadtxtStringIO 对象一起使用。
      • 漂亮的 numpy 魔法 :)
      【解决方案5】:

      @Joan,您的方法似乎是正确的。您可以使用列表理解一次按照您的建议进行操作:

      >>> s = "1,2,3 2,3,4 3,4,5 4,5,6 5,6,7 26,117,1212"
      >>> ' '.join([','.join([[n,'0'][int(i==1)] for i,n in enumerate(e.split(','))]) 
      ...    for e in s.split(' ')])
      1,0,3 2,0,4 3,0,5 4,0,6 5,0,7 26,0,1212
      

      或者,对于正在运行的i

      >>> print('\n'.join([' '.join([','.join([[n,'0'][int(i==j)] 
          for j,n in enumerate(e.split(','))]) for e in s.split(' ')]) 
          for i in range(3)]))
      0,2,3 0,3,4 0,4,5 0,5,6 0,6,7 0,117,1212
      1,0,3 2,0,4 3,0,5 4,0,6 5,0,7 26,0,1212
      1,2,0 2,3,0 3,4,0 4,5,0 5,6,0 26,117,0
      

      在任何情况下,s 首先在空格 ('') 处分割,每个生成的片段本身以逗号 (,) 分割,这样我们就可以遍历片段的单个元素,旁边是运行整数 [enumerate(seq)],我们用它测试每个元素是否是其片段的第 ith 项,在这种情况下,我们用 0 覆盖它。然后,通过使用join([...]) 函数重新插入相应的分隔符,我们将通过执行所有这些操作获得的嵌套列表自下而上重新组合成原始输入字符串格式。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-07-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-03-22
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多