为什么不以这种方式使用for循环替换列表中的每个项目?

2024-09-27 00:12:39 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个列表,如下所示:

['G1X0.000Y3.000', 'G2X2.000Y3.000I1.000J2.291', 'G1X2.000Y-0.000', 'G2X0.000Y0.000I-1.000J-2.291']

格式设置是这样的:如果X、Y、I或J之后的数字内容为正数,则没有+符号;如果为负数,则包含-符号。我试图循环浏览这个列表,如果数字内容的开头没有-号,则基本上添加+号。结果应该如下所示:

['G1X+0.000Y+3.000', 'G2X+2.000Y+3.000I+1.000J+2.291', 'G1X+2.000Y-0.000', 'G2X+0.000Y+0.000I-1.000J-2.291']

我尝试使用列表理解来实现以下目的:

#Make sure that X, Y, I and J start with + or - 
for count,i in enumerate(fileContents):
    if 'G' in i:
        indexOfI = i.index("X")
        if(i[indexOfI+1]!="-"):
            print(i[:indexOfI+1] + "+" + i[indexOfI+1:])
            fileContents[count] = i[:indexOfI+1] + "+" + i[indexOfI+1:]

        indexOfY = i.index("Y")
        if(i[indexOfY+1]!="-"):
            fileContents[count] = i[:indexOfY+1] + "+" + i[indexOfY+1:]

    if "G2" in i:
        indexOfI = i.index("I")
        if(i[indexOfI+1]!="-"):
            fileContents[count] = i[:indexOfI+1] + "+" + i[indexOfI+1:]

        indexOfJ = i.index("J")
        if(i[indexOfJ+1]!="-"):
            fileContents[count] = i[:indexOfJ+1] + "+" + i[indexOfJ+1:]

语句print(i[:indexOfI+1] + "+" + i[indexOfI+1:])在控制台中提供以下内容的输出:

G1X+0.000Y3.000
G2X+2.000Y3.000I1.000J2.291
G1X+2.000Y-0.000
G2X+0.000Y0.000I-1.000J-2.291

这向我表明,它执行我希望它执行的操作,但是如果在这个函数之后打印fileContents,则列表不会发生任何更改。换言之,以下代码行并不像我预期的那样替换每个位置中的列表项:

fileContents[count] = i[:indexOfI+1] + "+" + i[indexOfI+1:]

当我可以执行以下操作并且它可以正确更新列表时,为什么这不起作用

#Format each command to a 32 byte string
for i, s in enumerate(fileContents):
    fileContents[i] =s.ljust(32,'#')

编辑:我最初给这篇文章起名为“为什么不以这种方式使用列表理解替换列表中的每个项目?”。用户善意地指出,这与列表理解无关。很抱歉,我认为这种格式是一种列表理解


Tags: in内容列表indexif格式count符号
3条回答

循环中

for i, s in enumerate(fileContents):

您在fileContents列表上迭代,希望在同一循环中更改该列表。这总是很危险的

迭代此列表的副本,只需向其中添加[:]即可创建:

for i, s in enumerate(fileContents[:]):

您只需在这些字符之后添加+,然后用-替换回+-(f any):

def my_replace(item):
    for char in 'XYIJ':
        item = item.replace(char, f'{char}+')
    return item.replace('+-', '-')

spam = ['G1X0.000Y3.000', 'G2X2.000Y3.000I1.000J2.291',
        'G1X2.000Y-0.000', 'G2X0.000Y0.000I-1.000J-2.291']
eggs = [my_replace(item) for item in spam] # now, this is list comprehension
print(eggs)

输出

['G1X+0.000Y+3.000', 'G2X+2.000Y+3.000I+1.000J+2.291', 'G1X+2.000Y-0.000', 'G2X+0.000Y+0.000I-1.000J-2.291']

if I print fileContents after this function there are no changes to the list.

实际上,有变化,但最多添加一个(最后一个)

这是因为您没有对i应用相同的更改,这意味着下一个if块将把一个部分从i复制回fileContents[count]上一个更改没有的部分

快速修复方法是确保将更改应用到i。比如:

fileContents[count] = i = i[:indexOfI+1] + "+" + i[indexOfI+1:]
#                     ^^^^

您可以使用re.sub执行列表理解任务:

import re
fileContents = [re.sub(r"([XYIJ])(?=\d)", r"\1+", line) for line in fileContents]

这将匹配任何后跟数字的X、Y、I或J。在这种情况下,将在这些值之间插入一个加号。如果需要更严格的匹配规则,其中行必须以“G”、…等开头,那么正则表达式将变得更复杂

相关问题 更多 >

    热门问题