在Python中是否有优雅而简洁的语法?

时间:2014-02-20 05:13:57

标签: python string parsing

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

"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中做同样的事情可能有更好/更快更短的方法。

5 个答案:

答案 0 :(得分:2)

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

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

如果您要立即将数据转换回字符串,则不值得调用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) 中的1替换为您要替换的索引即可。第一个元素为row[1] = '0',第三个元素为0。您可以创建一个函数来获取您想要使用的索引:

2

答案 1 :(得分: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'

答案 2 :(得分:2)

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

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

答案 3 :(得分:1)

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

答案 4 :(得分:1)

@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([...])函数重新插入相应的分隔符来自下而上重新组装成原始输入字符串格式。