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日

悬赏问题

  • ¥60 版本过低apk如何修改可以兼容新的安卓系统
  • ¥25 由IPR导致的DRIVER_POWER_STATE_FAILURE蓝屏
  • ¥50 有数据,怎么建立模型求影响全要素生产率的因素
  • ¥50 有数据,怎么用matlab求全要素生产率
  • ¥15 TI的insta-spin例程
  • ¥15 完成下列问题完成下列问题
  • ¥15 C#算法问题, 不知道怎么处理这个数据的转换
  • ¥15 YoloV5 第三方库的版本对照问题
  • ¥15 请完成下列相关问题!
  • ¥15 drone 推送镜像时候 purge: true 推送完毕后没有删除对应的镜像,手动拷贝到服务器执行结果正确在样才能让指令自动执行成功删除对应镜像,如何解决?