qhc12345 2023-01-02 22:57 采纳率: 100%
浏览 18
已结题

为何python里没有使用global函数但是函数里对于变量的操作影响到了外面

Hi 大家好。我是一个高中生,没系统学习过python,靠着学过的一些c++的皮毛和看论坛还有一些实践学的python
最近在写竞赛编程题的时候遇到了这么一个问题
__
我在自己定义的函数内的局部变量(好像是叫这个)和函数外面的变量取了相同的名字(我知道不应该这么做,但是我想着理论上应该没什么问题),除了algo1函数外所有调用全局变量的形式都是写在函数后面的括号里而不是用global进行的操作。可是当我在第一个副函数里操作完函数引入变量以后,line1和line2这两个函数变成了全局变量,我在函数里对他们进行的操作直接影响了函数外面的部分
__
我另起了一个程序,极度简单的复刻了一下重要的操作,可是并没有什么用。
我一开始在想会不会是因为一开始写的时候用了global,导致下面编译了以后的操作会直接影响,可是在我删除了以后还是这样。就很奇怪
__
为了方便理解我的史山代码,这里是题目:
给予两串字符串形式的句子,要求把第一串字符串中每一个单词都和第二串字符串中的每一个单词做比较,如果存在于第二串字符串中则把这个单词记下来,并且把第二串中的这个单词的部分删掉。
然后为第二串字符串比较第一串字符串,运用相同的规则
例:第一串中的单词“jump”存在于第二串中的单词“overjump”,那么记住单词“jump”,把第二串中的”overjump“中的”jump“部分删除,留下”over“
__
由于第一次为了让别人看懂我的代码写注释不知道应该怎么写,可能写的有点迷惑,见谅
代码下面符了一张报错的内容

def algo1(line1,line2):          #主要的大函数,用来套住两次比较
  #global line1                         这里是原来写的global的位置
  #global line2                         这里是原来写的global的位置
  ans1=FtoS(line1,line2)      #这个函数用来比较第一个和第二个
  print("////")
  ans2=StoF(line1,line2)      #这个函数用来比较第二个和第一个,内容本质上没什么区别,可能有逻辑错误
  return ans1,ans2

def FtoS(line1,line2):        #这个函数用来比较第一个和第二个
  result=[]       #储存相同单词
  for i in line1:
    for pos,j in enumerate(line2):    #循环嵌套来比较
      if len(i)<=len(j):    #排除单词1比单词2多的情况,避免超出下标
        ans=judge(i,j)    #将比较的返回值存进去
        if ans!=j:            #如果不相等,说明单词2有更新,那么进行操作
          # print(type(i))
          result.append(i)   #把这个单词添加进result内
          # print(ans)
          line2[pos]=ans     #把list内的这个单词替换掉
          break
  return result

def StoF(line1,line2):   #本质上和前面那个一模一样,只是把两个list的位置换了一下
  result=[]
  print(line2)
  for i in line2:
    print(i)
    for pos,j in enumerate(line1):
      if len(i)<=len(j):
        ans=judge(i,j)
        if ans!=j:
          result.append(i)
          line1[pos]=ans
          break
  return result

def judge(s1,s2):    #用来比较单词
  print(s1,s2)    #debug用
  l1=[i for i in s1]   #将单词1变成字符
  l2=[i for i in s2]   #将单词1变成字符
  # print(l1,l2)
  ans=''    #整合字符用
  stt=0     #记录状态
  pos=0   #记录位置
  for i in range(len(l2)):   #先通过循环来寻找有没有相同的字母,有并定位。但是这个不完善,可能会出现无法识别的情况,但是先不去考虑
    # print(l1[0],l2[i])
    if l2[i]==l1[0]:
      pos=i   #定位
      break
  for i in range(len(l1)):   #定位后判断是不是后面的是不是都一样。这个应该写在前面那个循环break的位置,但是能跑起来我就别去动了
    if l2[pos+i]!=l1[i]:
      stt=1    #如果发现有位置不一样,那么状态变量变成1
      break
  if stt==0:   #如果状态变量是0,说明找到了
    for i in range(len(l1)):
      l2.pop(pos)   #将相同的部分去除
  for i in l2:   #整合
    ans+=i
  return ans   #返回值



# line1=input("1:")
# line2=input("2:")
line1='The quick brown fox did jump over a log'                #句子1
line2='The brown rabbit quickly did outjump the fox'         #句子2
line1=line1.split(' ')      #把句子分隔成单词
line2=line2.split(' ')      #把句子分隔成单词
print(algo1(line1,line2))       #调用主函数并输出

img

  • 写回答

1条回答 默认 最新

  • 於黾 2023-01-03 08:52
    关注

    line1和line2是list
    list是可变值类型
    所以你在给形参append或者del的时候会直接改变实参
    但是如果你给形参执行等号赋值,就是将它们重新指向了新的地址,那么就跟实参无关了
    其实抛开形参实参不谈,你执行下面的代码试试就知道了
    a=[]
    b=a
    b.append(1)
    print(a)
    你会发现你修改的是b,但是a也变了

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论 编辑记录

报告相同问题?

问题事件

  • 系统已结题 1月13日
  • 已采纳回答 1月5日
  • 创建了问题 1月2日

悬赏问题

  • ¥15 用stata实现聚类的代码
  • ¥15 请问paddlehub能支持移动端开发吗?在Android studio上该如何部署?
  • ¥170 如图所示配置eNSP
  • ¥20 docker里部署springboot项目,访问不到扬声器
  • ¥15 netty整合springboot之后自动重连失效
  • ¥15 悬赏!微信开发者工具报错,求帮改
  • ¥20 wireshark抓不到vlan
  • ¥20 关于#stm32#的问题:需要指导自动酸碱滴定仪的原理图程序代码及仿真
  • ¥20 设计一款异域新娘的视频相亲软件需要哪些技术支持
  • ¥15 stata安慰剂检验作图但是真实值不出现在图上