找回密码
 立即注册

扫一扫,访问微社区

QQ登录

只需一步,快速开始

查看: 1160|回复: 2

[求助] list.extend() 处理数据 与预期不一致

0

主题

2

帖子

2

积分

贫民

积分
2
junyee 发表于 2021-11-23 17:22:05 | 显示全部楼层 |阅读模式
本帖最后由 junyee 于 2021-11-23 17:24 编辑

    大家好,我是一个新手python 玩家.

有一串数据,如:

T01
[[
X000906Y009567
X000906Y009075
]]M02
M02X0Y017569
M02X013228Y-017569
M02X-13228Y0
END

我想让python程序逐行解析。
碰到  "[[ ... ]]" 的块则临时存储到一个块中,
遇到 M02X#Y# 后再对块存储的数据进行 加运算。

期待的运行后结果(请忽略 注释##//):
T01

X000906Y009567
X000906Y009075

##// X+=0   , Y+=17569
X000906Y27136
X000906Y26644

##// X+=13228,Y-=17569
X14134Y9567
X14134Y9075

##// X+=-13228 Y+=0
X906Y9567
X906Y9075
END

我试着用一段简单的python脚本来处理它,但是得到的结果与预期的不同。

  1. #! python3
  2. ##coding:utf-8
  3. import re

  4. input='''
  5. T01
  6. [[
  7. X000906Y009567
  8. X000906Y009075
  9. ]]
  10. M02
  11. M02X0Y017569
  12. M02X013228Y-017569
  13. M02X-13228Y0
  14. END
  15. '''

  16. drils={}
  17. drils["lines"]=input.split('\n')

  18. def parse_line(l):  
  19.     xy = ('X' in l) or ('Y' in l)
  20.     if (xy==False): return {"name":l};

  21.     match=re.search( r'([^XY]*)X?([\d\-]*)Y?([\d\-]*)' , l )
  22.     name= match.group(1) or ""
  23.     x= match.group(2) or 0
  24.     y= match.group(3) or 0
  25.     x= int(x)
  26.     y= int(y)

  27.     return {"name":name,"x": x,"y": y}


  28. cat=None
  29. pattern=[]
  30. codes=[]
  31. for l in drils["lines"]:

  32.     if ( cat==True ) :
  33.         if (l=="]]"):    ##END_OF_PATTERN
  34.             cat = None
  35.             print('.. quit cat \n')
  36.             continue
  37.         pattern.append( parse_line(l) )
  38.         continue

  39.     if (l=="[["):
  40.         print('enter cat ..')
  41.         ##pattern.clear()
  42.         cat=True
  43.         continue

  44.     if (l.startswith("M02")):    ##CALC_PATTERN
  45.         if (l=="M02"):
  46.             xy={"x":0,"y":0}
  47.         else:
  48.             xy=parse_line(l)

  49.         print("  calc_pattern: ", l )
  50.         for i,v in enumerate(pattern):
  51.             pattern[i]["x"] += xy["x"]
  52.             pattern[i]["y"] += xy["y"]

  53.         codes.extend( pattern)    ##
  54.         continue

  55.     ## !!! ELSE   
  56.     xy =parse_line(l)
  57.     codes.append( xy )


  58. ##print( str(codes) )
  59. for v in codes:
  60.     if v.get("x"):
  61.         print( "%sX%dY%d" % (v["name"],v["x"],v["y"]) )
  62.     else:
  63.         print( "%s" % (v["name"]) )
复制代码




得到的结果是:
__截图20211123171456.png

得到4组结果 全都是最终结果,我用了好几小时还是没找问题所在,故而到论坛向各位大侠求助

问题定位在
codes.extend( pattern)        ########

通过插入 print 调试代码可知 , 两个list( pattern 和 codes )得的数据都是正确的,但将 pattern 附加到 codes 就出了错。






回复

使用道具 举报

0

主题

2

帖子

2

积分

贫民

积分
2
junyee  楼主| 发表于 2021-11-24 10:06:57 | 显示全部楼层



  1. #! python3
  2. ##coding:utf-8
  3. import re

  4. input='''
  5. T01
  6. [[
  7. X000906Y009567
  8. X000906Y009075
  9. ]]
  10. M02
  11. M02X0Y017569
  12. M02X013228Y-017569
  13. M02X-13228Y0
  14. END
  15. '''

  16. drils={}
  17. drils["lines"]=input.split('\n')

  18. def parse_line(l):  
  19.     xy = ('X' in l) or ('Y' in l)
  20.     if (xy==False): return {"name":l};

  21.     match=re.search( r'([^XY]*)X?([\d\-]*)Y?([\d\-]*)' , l )
  22.     name= match.group(1) or ""
  23.     x= match.group(2) or 0
  24.     y= match.group(3) or 0
  25.     x= int(x)
  26.     y= int(y)

  27.     return {"name":name,"x": x,"y": y}


  28. cat=None
  29. pattern=[]
  30. codes=[]
  31. for l in drils["lines"]:

  32.     if ( cat==True ) :
  33.         if (l=="]]"):    ##END_OF_PATTERN
  34.             cat = None
  35.             print('.. quit cat \n')
  36.             continue
  37.         pattern.append( parse_line(l) )
  38.         continue

  39.     if (l=="[["):
  40.         print('enter cat ..')
  41.         ##pattern.clear()
  42.         cat=True
  43.         continue

  44.     if (l.startswith("M02")):    ##CALC_PATTERN
  45.         if (l=="M02"):
  46.             xy={"x":0,"y":0}
  47.         else:
  48.             xy=parse_line(l)

  49.         
  50.         print("  calc_pattern: ", l )
  51.         print( str(codes) )
  52.         for i,v in enumerate(pattern):
  53.             pattern[i]["x"] += xy["x"]
  54.             pattern[i]["y"] += xy["y"]
  55.         print( str(codes) , "\n" )

  56.         codes.extend( pattern)    ##
  57.         continue

  58.     ## !!! ELSE   
  59.     xy =parse_line(l)
  60.     codes.append( xy )


  61. ##print( str(codes) )
  62. for v in codes:
  63.     if v.get("x"):
  64.         print( "%sX%dY%d" % (v["name"],v["x"],v["y"]) )
  65.     else:
  66.         print( "%s" % (v["name"]) )
复制代码


加了一把 print,
问题出现在  62-66间。
for 循环是对  pattern[x] 和 pattern[y] 进行加法运算的,
但是结果同时影响到了 codes[][x] , codes[][y] .

感觉就像是 C  中的不同的指针指向了同一个地址,操作一个解指针数据,其它指针数据也跟着变化。

恕我愚钝,没找出问题具体出在哪
等高人前来指点。



回复 支持 反对

使用道具 举报

0

主题

2

帖子

2

积分

贫民

积分
2
junyee  楼主| 发表于 2021-11-24 10:40:50 | 显示全部楼层

既然想到C的指针,会不会 python 就是这样工作的呢,如果是这样的话,这个变量赋值运算就很让新人迷惑。

搜索了下,果然论坛也有类似的疑问。
如:
https://bbs.pythontab.com/forum. ... =%E5%BC%95%E7%94%A8

其中版主有如下的回复:
我觉得你这个可能是浅复制,


于是到网上搜索了 python 浅复制,果然验证了我的猜想。

对于新出现的可变对象,默认就是浅复制。

---

最后,
改了下代码:
  1. ##codes.extend( pattern)
  2. codes.extend( copy.deepcopy(pattern) )

复制代码


完工。





回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表