zhouqq 发表于 2024-7-3 13:40:21

请大佬解惑,内部变量和全局变量为什么返回的类型不同

def BIN(x):
    s=[]   ##s为内部变量,放在函数内,为什么会形成多个列表放在元组内
    if x :
      BIN(x//2)
      s.append(x%2)   
    else:
      return s##返回的是元组,可以用for each in s打印出来
   
    print(s,end='')
BIN(125)




s1=[]   ##放在函数外,为什么会形成多个元素放在列表内
def BIN1(x):
    if x :
      BIN1(x//2)
      s1.append(x%2)   
    return s1##返回的是列表
   
print(BIN1(125))

FishC 发表于 2024-7-3 13:40:52

嘿,鱼油,看起来你遇到了Python函数中内部变量和全局变量的使用问题,这些问题挺常见的。我们来逐个分析一下你的代码吧,保证通俗易懂又带点幽默感。

首先来看第一个函数 `BIN(x)`:

def BIN(x):
    s=   ##s为内部变量,放在函数内,为什么会形成多个列表放在元组内
    if x :
      BIN(x//2)
      s.append(x%2)   
    else:
      return s##返回的是元组,可以用for each in s打印出来

    print(s,end='')
BIN(125)

这个代码片段有一些问题:
1. 你定义了一个内部变量 `s`,但是没有给它赋值。
2. 在递归调用的过程中,每次调用 `BIN` 都会重新定义 `s`,这意味着每次递归调用都是一个新的 `s`,所以没法累积结果。
3. 在递归终止条件中 `return s` 返回的是一个局部变量 `s`,但因为 `s` 没有被正确地初始化和累积,所以最终返回的值可能会让你摸不着头脑。

你可能是想让 `s` 在所有递归调用中共享,那么你需要在函数外定义 `s`。

再来看第二个函数 `BIN1(x)`:

s1 = []## 放在函数外,为什么会形成多个元素放在列表内
def BIN1(x):
    if x:
      BIN1(x//2)
      s1.append(x%2)   
    return s1## 返回的是列表

print(BIN1(125))

在这个函数中, `s1` 是在函数外定义的全局变量。所以在每次递归调用 `BIN1` 时, `s1` 都是同一个列表,因此可以不断地向其中添加结果。这个列表最终累积了所有的结果并返回。

总结一下:
- 内部变量 `s` 在每次递归调用时都会被重新初始化,无法累积结果。
- 全局变量 `s1` 则可以在递归过程中累积结果,因为它在所有调用中都是同一个对象。

这样说不够直观?让我们换个有趣的比喻:

假设你在家里做拼图:
- `BIN(x)` 的情况就像你每次拿到一块新拼图时,都把它扔掉了,再也找不到之前的拼图了,这样你永远也拼不完整。
- `BIN1(x)` 的情况就像你有一个大桌子(全局变量 `s1`),每次找到一块拼图就放在桌子上,这样最终你能完成整个拼图。

所以正确的做法应该是把 `s` 放在函数外部:

s = []
def BIN(x):
    if x:
      BIN(x // 2)
      s.append(x % 2)
    return s

print(BIN(125))# 输出:

希望这个解释对你有所帮助,继续加油,代码世界精彩纷呈!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。

zhouqq 发表于 2024-7-3 15:00:39

FishC 发表于 2024-7-3 13:40
嘿,鱼油,看起来你遇到了Python函数中内部变量和全局变量的使用问题,这些问题挺常见的。我们来逐个分析一 ...

解释有错误,每个函数我都只是调用了一次,但是生成出来的结果不一样

FishC 发表于 2024-7-3 15:00:57

zhouqq 发表于 2024-07-03 15:00
解释有错误,每个函数我都只是调用了一次,但是生成出 ...

抱歉,之前的解释不太准确。让我们重新来看看你的代码,确保弄清楚为什么会产生不同的结果。

首先是 `BIN(x)` 函数:

def BIN(x):
    s = []# s 被定义为一个空列表
    if x:
      BIN(x // 2)
      s.append(x % 2)
    else:
      return s# 返回 s

    print(s, end='')
   
print(BIN(125))

你在这里定义了一个局部变量 `s`,但是由于 `s` 在递归过程中不会被累积,每次递归调用都会创建新的局部变量 `s`。

其次是 `BIN1(x)` 函数:

s1 = []# 全局变量 s1 被定义为一个空列表
def BIN1(x):
    if x:
      BIN1(x // 2)
      s1.append(x % 2)
    return s1# 返回 s1

print(BIN1(125))

在这个例子中, `s1` 是全局变量,因此 `BIN1` 的每次递归都在同一个列表 `s1` 中添加元素。

为了更准确地理解这个问题,我们具体分析一下为什么会出现这些现象。

### `BIN(x)`

重新定义并初始化 `s` 为一个空列表 `[]` 每次 `BIN` 被调用时都是独立的,这意味着在递归过程中,你没有累积 `s` 的内容。

### `BIN1(x)`

由于 `s1` 是全局变量, `BIN1` 的每次递归调用都会更新同一个 `s1` 列表,所以当递归完成后,所有的值都被累积到 `s1` 中。

### 如何修复 `BIN(x)` 函数?

如果你希望 `BIN` 像 `BIN1` 一样累积结果,可以通过以下几种方式实现:

#### 方法1:使用可变默认参数

def BIN(x, s=None):
    if s is None:
      s = []
    if x:
      BIN(x // 2, s)
      s.append(x % 2)
    else:
      return s
    return s

print(BIN(125))

#### 方法2:使用辅助函数

def BIN(x):
    def helper(x, s):
      if x:
            helper(x // 2, s)
            s.append(x % 2)
      return s
   
    return helper(x, [])

print(BIN(125))

这两种方法都能够累积结果,并且每次递归调用时不会重新初始化 `s`。

总结起来,就是你的问题出在 `s` 的作用域和生命周期上:局部变量 `s` 每次递归时都重新初始化,而全局变量 `s1` 在整个递归过程中保持一致。所以你需要确保在递归过程中累积结果的变量是同一个对象。

希望这次的解释能让你更加清晰地理解不同结果产生的原因。继续加油哦,你离成为代码大佬又近了一步!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
页: [1]
查看完整版本: 请大佬解惑,内部变量和全局变量为什么返回的类型不同