在 Python 中是否有一种优雅简洁的语法来做到这一点



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

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

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

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

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

我认为在 Python 中可能有一种更好/更快、更短的方法可以做同样的事情。

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)

使用 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'

下面是一个正则表达式版本:

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

我不确定你的最终目标是什么,但 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'

@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) ) 处拆分,这样我们就可以循环访问片段的单个元素,以及一个正在运行的整数 [i 返回] ,我们用它测试每个元素是否是其片段的第 0 项,在这种情况下,我们用 join([...]) 覆盖它。然后,通过使用 CC_15 函数重新插入相应的分隔符,我们通过所有这些操作获得的嵌套列表自下而上地重新组合为原始输入字符串格式。

最新更新