【python】变量作用域_集合_列表_字典_元祖

变量作用域_集合_列表_字典_元祖

    • 变量作用域
      • 提升局部变量为全局变量
      • globals, locals函数
    • eval()函数
    • exec()函数
    • 递归函数
      • 斐波那契数列
  • 内置数据结构(变量类型)
    • list[列表]
      • 创建列表
      • 访问列表
      • 分片操作
        • 分片操作是生成一个新的list
      • copy:拷贝,浅拷贝(只拷贝一层内容,不同id)
      • del:删除
      • clear:清空
      • 乘号操作列表,相当于复制n次
      • in:判断元素是否在一个list里面
      • count:差找指定值或元素的个数
      • 遍历
      • 对列表a内所有元素乘以10
      • len:求列表长度
      • max:求列表中最大值
      • 将其他格式转化为list
      • append:列表内添加元素
      • extend:扩展列表,把一个直接接在末尾
      • insert:在指定位置插入
      • pop:把队尾元素取出来
      • remove:在列表中删除指定的值
      • reverse:翻转列表内容,原地翻转
    • tuple(元祖)
      • 创建
      • 特性
      • 元组变量交换法 : a,b = b,a
    • set{集合}
      • 创建
      • 特征
      • 带有元组的集合遍历
      • discard:移除指定的值
      • pop:随机移除一个元素
      • 集合函数:并交叉
    • 字典{dict}
      • 创建
      • 特征
      • 常见操作
        • d["one"]:访问数据
        • in,not in:成员检测,检测的是key
        • 遍历,对key遍历
        • 字典生成式
        • 相关函数
        • d.items():返回键值对应元组格式
        • d.keys():返回键组成的结构
        • d.values():一个可迭代的结构
        • d.get():根据制定见返回相应值,可设置默认值
        • d.fromkeys():使用指定雪猎作为键,使用一个值作为字典所有键的值
    • 冰冻集合(frozen set)

变量作用域

  • 变量由作用范围限制
  • 分类:按照作用域分类
    • 全局(global): 在函数外部定义
    • 局部(local):在函数内部定义
  • 变量的作用范围:
    • 全局变量:在整个全局范围都有效
    • 全局变量在局部可以使用(即函数内部可以方位函数外部定义的变量)
    • 局部变量在局部范围可以使用
    • 局部变量在全局范围无法使用
  • LEGB原则
    • L(Local)局部作用域
    • E(Enclosing function locale)外部嵌套函数作用域
    • G(Global module)函数定义所在模块作用域
    • B(Buildin): python内置魔抗的作用域

提升局部变量为全局变量

  • 使用global
  • 案例如下
def fun():
    global b1
    b1 = 100
    print(b1)
    print("I am in fun")
    # a2的作用范围是fun
    b2 = 99
    print(b2)

fun()
# print(b1)如果在函数调用上面,则不好使,报错,为什么???
print(b1)
100
I am in fun
99
100

globals, locals函数

  • 可以通过globals和locals显示出局部变量和全局变量

eval()函数

  • 把一个字符串当成一个表达式来执行, 返回表达式执行后的结果

  • 语法:

          eval(string_code, globals=None, locals=None)
    

exec()函数

  • 跟eval功能类似, 但是,不返回结果

  • 语法:

      exec(string_code, globals=None, locals=None)
    
x = 100
y = 200
# 执行x+y
# z = x + y
z1 = x + y
z2 = eval("x+y")

print(z1) # 300
print(z2) # 300
# exec示例
x = 100
y = 200
# 执行x+y
# z = x + y
z1 = x + y
# 1, 注意字符串中引号的写法
# 2. 比对exec执行结果和代码执行结果
z2 = exec("print('x+y:', x+y)")

print(z1)
print(z2)
x+y: 300
300
None

递归函数

  • 含直接或者间接调用自身
  • 优点:简洁,理解容易
  • 缺点:对递归深度有限制,消耗资源大
  • python对递归深度有限制,超过限制报错
  • 在写递归程序的时候,一定注意结束条件
# 递归调用深度限制代码

x = 0

def fun():
    global x
    x += 1
    print(x)
    # 函数自己调用自己
    fun()
    
# 调用函数
fun()   #输出:从0到1965,报错

斐波那契数列

# 一列数字,第一个值是1, 第二个也是1, 从第三个开始,每一个数字的值等于前两个数字出现的值的和
# 数学公式为: f(1) = 1, f(2) = 1, f(n) = f(n-1) + f(n-2)
# 例如: 1,1,2,3,5,8,13.。。。。。。。。

# 下面求斐波那契数列函数有一定问题,比如n一开始就是负数,如何修正
# n表示求第n个数子的斐波那契数列的值
def fib(n):
    if n == 1:
        return
    if n == 2:
        return 1
    return fib(n-1) + fib(n-2)

print(fib(3))
print(fib(10))

内置数据结构(变量类型)

  • list
  • set
  • dict
  • tuple

list[列表]

  • 一组由顺序的数据的组合
  • 创建列表
    • 空列表

创建列表

# 1, 创建空列表
l1 = []
# type是内置函数,负责打印出变量的类型
print(type(l1))
print(l1)

# 2. 创建带值的列表
l2 = [100]
print(type(l2))
print(l2)

# 3. 创建列表,带多个值
l3 = [2,3,1,4,6,4,6]
print(type(l3))
print(l3)

[]

[100]

[2, 3, 1, 4, 6, 4, 6]

访问列表

# 下标访问列表
l = [3,2,1,4,6,3,2]

print(l[3]) # 4

分片操作

l = [3,2,1,4,6,3,2]
# 注意截取的范围,包含左边的下标值,不包含右边的下标值
print(l[1:4])  # [2, 1, 4]

# 下标值可以为空,如果不写,左边下标值默认为0, 右边下标值为最大数加一,即表示截取到最后一个数据
print(l[:])  #[3, 2, 1, 4, 6, 3, 2]
print(l[:4])  #[3, 2, 1, 4]
print(l[2:])   #[1, 4, 6, 3, 2]

# 打印从下标1开始的数字,每次隔一个
print(l[1:6:2])  #[2, 4, 3]

# 分片之负数下标
# 下面显示的是为空,因为默认分片总是从左向右截取
# 即正常情况,分片左边的值一定小于右边的值
print(l[-2:-4]) #[]
print(l[-4:-2]) #[4, 6]
# 如果分片一定左边值比右边大,则步长参数需要使用负数
# 此案例为一个list直接正反颠倒提供了一种思路
print(l[-2:-4:-1]) #[3, 6]

分片操作是生成一个新的list

  • 内置函数id,负责显示一个变量或者数据的唯一确定编号。(类比地址)
# id函数举例
a = 100
b = 200
print(id(a))   #93941189949760
print(id(b))   #93941189952960

c = a
print(id(c))   #93941189949760
c和a的id相同

# 如果a跟c只想一份数据,则更改a的值同样也会更改c的值
# 但是,显示结果并非如此,为什么?
a = 101
print(a)  #101
print(c)  #100
  • 通过id判断分片是重新生成了一份数据还是用的同一个list
# 通过id可以直接判断出分片是从新生成了一份数据还是使用的同一份数据
l = [3,4,56,76,32,21,43,5]
ll = l[:]
lll = ll
# 如果两个id值一样,则表明分片产生的列表是使用的同一地址同一份数据
# 否则,则表明分片是从新生成了一份数据,即一个新的列表,然后把数值拷贝到新列表中
print(id(l))    #140226763582408
print(id(ll))   #140226318124808
print(id(lll))  #140226318124808

# 通过id知道,ll和lll是同一份数据,验证代码如下
l[1] = 100
print(l)   #[3, 100, 56, 76, 32, 21, 43, 5]
print(ll)  #[3, 4, 56, 76, 32, 21, 43, 5]

ll[1] = 100
print(ll)  #[3, 100, 56, 76, 32, 21, 43, 5]
print(lll) #[3, 100, 56, 76, 32, 21, 43, 5]

copy:拷贝,浅拷贝(只拷贝一层内容,不同id)

# 列表类型变量赋值示例
a = [1,2,3,4,5,666]
print(a)
# list类型,简单赋值操作,是传地址
b = a
b[3] = 777
print(a) 
print(id(a))
print(b)
print(id(b))

print("*" * 20)

# 为了解决以上问题,list赋值需要采用copy函数
b = a.copy()
print(a)
print(id(a))
print(b)
print(id(b))
print("*" * 30)
b[3] = 888
print(a)
print(b)
[1, 2, 3, 4, 5, 666]
[1, 2, 3, 777, 5, 666]
140249408975432
[1, 2, 3, 777, 5, 666]
140249408975432
********************
[1, 2, 3, 777, 5, 666]
140249408975432
[1, 2, 3, 777, 5, 666]
140249408976776
******************************
[1, 2, 3, 777, 5, 666]
[1, 2, 3, 888, 5, 666]
# 深拷贝跟浅拷贝的区别
# 出现下列问题的原因是,copy‘函数是个浅拷贝函数,即只拷贝一层内容
# 深拷贝需要使用特定工具
a = [1,2,3, [10, 20, 30]]
b = a.copy()
print(id(a))
print(id(b))
print(id(a[3]))
print(id(b[3]))
a[3][2] = 666
print(a)
print(b)
140249408365768
140249409236040
140249409236232
140249409236232
[1, 2, 3, [10, 20, 666]]
[1, 2, 3, [10, 20, 666]]

del:删除

# del 删除
# 删除后生成了一个新的list
a = [1,2,3,4,5,6]
del a[2]
print(a)  #[1, 2, 4, 5, 6]
del a
print(a) #报错

clear:清空

  • 清空列表,列表本身还在。

乘号操作列表,相当于复制n次

a = [1,2,3,4,5]
b = a *3
print(b)  #[1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5]

in:判断元素是否在一个list里面

a = [1,2,3,4,5,6]
b = 8
#c 的值是一个布尔值
c = b in a
print(c)  #False
print(b not in a) #True

count:差找指定值或元素的个数

# count:查找列表中指定值或元素的个数
print(a)
a.append(8)
a.insert(4, 8)
print(a)
a_len = a.count(8)
print(a_len)
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 8]
[1, 2, 3, 4, 8, 5, 6, 7, 8, 9, 10, 8, 8]
4

遍历

# for in list
a = [1,2,3,4,5]

# 挨个打印a里边的元素
for i in a:
    print(i)
1
2
3
4
5
# range
# in 后面的变量要求是可以可迭代的内容
for i in range(1,10):
    print(i)
# 双层列表循环变异

#a 为嵌套列表,或者叫双层列表
a = [["one", 1, "eins"], ["two", 2,"zwei"], ["three", 3,"drei"] ]
#这个例子说明,k,v,w的个数应该跟解包出来的变量个数一致
for k,v,w in a:
    print(k, "--", v, "--",w)

对列表a内所有元素乘以10

# 对a中所有元素乘以10,生成一个新list
a = [1,2,3,4,5]
# 用list a创建一个list b
# 下面代码的含义是,对于所有a中的元素,逐个放入新列表b中
b = [i*10 for i in a]
print(b)  #[10, 20, 30, 40, 50]
# 还可以过滤原来list中的内容并放入新列表
# 比如原有列表a,需要把所有a中的偶数生成新的列表b

a = [x for x in range(1,35)] #生成从1到34的一个列表
# 把a中所有偶数生成一个新的列表 b
b = [m for m in a if m % 2 == 0]
print(b)

len:求列表长度

len(a)

max:求列表中最大值

max(a)

将其他格式转化为list

s = "I love wangxiaojing"
print(list(s))  #['I', ' ', 'l', 'o', 'v', 'e', ' ', 'w', 'a', 'n', 'g', 'x', 'i', 'a', 'o', 'j', 'i', 'n', 'g']

append:列表内添加元素

# append 插入一个内容, 在末尾追加
a = [ i for i in range(1,5)]
print(a) #[1, 2, 3, 4]
a.append(100)
print(a) #[1, 2, 3, 4, 100]

extend:扩展列表,把一个直接接在末尾

a = [ 1,2,3,4,5]
b = [6,7,8,9,10]
print(a)
print(id(a))

a.extend(b)

print(a)
print(id(a))
[1, 2, 3, 4, 5]
140249408367816
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
140249408367816

insert:在指定位置插入

#insert(index,data) 插入位置死index前面
a.insert(3,666)
print(a) #[1, 2, 3, 666, 4, 100]

pop:把队尾元素取出来

remove:在列表中删除指定的值

  • remove操作是在原list直接操作
a.remove(666)
print(a) #[1, 2, 3, 4]

reverse:翻转列表内容,原地翻转

a = [ 1,2,3,4,5]
print(a)
print(id(a))
a.reverse()


print(a)
print(id(a))
[1, 2, 3, 4, 5]
140249409135624
[5, 4, 3, 2, 1]
140249409135624

tuple(元祖)

  • 元组可以看成是一个不可更改的list

创建

# 创建空元组
t = ()
# 创建一个只有一个值的元组
t = (1,)

t = 1,
# 创建多个值的元组
t = (1,2,3,4,5)

t =  1,2,3,4,5

# 使用其他结构创建
l = [1,2,3,4,5]
t = tuple(l)

特性

  • 是序列表,有序
  • 元组数据值可以访问,不能修改
  • 元组数据可以是任意类型
  • list所有特性,除可修改外,都具有

元组变量交换法 : a,b = b,a

set{集合}

  • 一堆确定的无序的唯一的数据,其中每一个数据称为一个元素

创建

s = set()
s = {1, 2, 3, 4, 5, 7}

特征

  • 集合内数据无序,无法使用索引和分片
  • 集合内部数据具有唯一性,用来排除重复数据
  • 集合内的数据,str、int、float、tuple等

带有元组的集合遍历

# 带有元组的集合遍历
s = {(1,2,3), ("i", "love", "wangxiaojing"), (4,5,6)}

for k,m,n in s:
    print(k, "--", m, "--", n)
    
for k in s:
    print(k)
4 -- 5 -- 6
i -- love -- wangxiaojing
1 -- 2 -- 3
(4, 5, 6)
('i', 'love', 'wangxiaojing')
(1, 2, 3)

discard:移除指定的值

pop:随机移除一个元素

集合函数:并交叉

集合函数
# intersection: 交集
# difference:差集
# union: 并集
# issubset: 检查一个集合是否为另一个子集
# issuperset: 检查一个集合是否为另一个超集
s1 = {1,2,3,4,5,6}
s2 = {5,6,7,8,9}

s_1 = s1.intersection(s2)
print(s_1)

s_2 = s1.difference(s2)
print(s_2)

s_3 = s1.issubset(s2)
print(s_3)    #False

字典{dict}

  • 组合数据,没有顺序,数据以键值对形式存在

创建

# 字典的创建
# 创建空字典1
d = {}
# 创建空字典2
d = dict()
# 创建有值的字典, 每一组数据用冒号隔开, 每一对键值对用逗号隔开
d = {"one":1, "two":2, "three":3}
# 用dict创建有内容字典1
d = dict({"one":1, "two":2, "three":3})
# 用dict创建有内容字典2
# 利用关键字参数
d = dict(one=1, two=2, three=3)

# 
d = dict( [("one",1), ("two",2), ("three",3)])
print(d)
{'one': 1, 'two': 2, 'three': 3}

特征

  • 字典是序列类型吗但是是无序序列,没有分片和索引
  • 字典中的数据每个都有键值对组成,即kv对
    • key:必须是可哈希的值,比如int,string,float,tuple
    • 不可以list,set,dict
    • value:任何值

常见操作

d[“one”]:访问数据

d = {"one":1,"two":2,"three":3}
print(d["one"])  #1
d["one"] = "eins"
print(d)  #{'one':eins,'two':2,'three':3}

in,not in:成员检测,检测的是key

d = {"one":1, "two":2, "three":3}

if 2 in d:
    print("value")
    
if "two" in d:
    print("key")
    
if ("two",2) in d:
    print("kv")  #key

遍历,对key遍历

d = {"one":1, "two":2, "three":3}
for k in d:
    print(k, d[k])  #one 1
                    #two 2
                    #three 3
#只访问字典的值:
for v in d.values():
    print(v)    #1
                #2
                #3
#注意以下特殊用法
for k,v in d.items():
    print(k,'--',v)     #one--1
                        #two--2
                        #three--3

字典生成式

  • 常规字典生成
dd = {k:v for k,v in d.items()}
  • 加限制生成
dd = {k:v for k,v in d.items() if v%2 == 0}

相关函数

  • 通用函数:len,max,min,dict
  • str(字典):返回字符串的字符串格式
    print(ste(d))
    {‘one’: 1, ‘two’: 2, ‘three’: 3}

d.items():返回键值对应元组格式

d = {"one":1, "two":2, "three":3}
i = d.items()
print(type(i))  #
print(i)  #dict_items([('one', 1), ('two', 2), ('three', 3)])

d.keys():返回键组成的结构

# keys:返回字典的键组成的一个结构
k = d.keys()
print(type(k))  #
print(k)  #dict_keys(['one', 'two', 'three'])

d.values():一个可迭代的结构

  • print(v) #dict_values([1, 2, 3])

d.get():根据制定见返回相应值,可设置默认值

 get: 根据制定键返回相应的值, 好处是,可以设置默认值

d = {"one":1, "two":2, "three":3}
print(d.get("on333"))

# get默认值是None,可以设置
print(d.get("one", 100))
print(d.get("one333", 100))

#体会以下代码跟上面代码的区别
print(d['on333']) #报错
None
1
100

d.fromkeys():使用指定雪猎作为键,使用一个值作为字典所有键的值

l = ["eins", "zwei", "drei"]
# 注意fromkeys两个参数的类型
# 注意fromkeys的调用主体
d = dict.fromkeys(l, "hahahahahah")
print(d) #{'eins': 'hahahahahah', 'zwei': 'hahahahahah', 'drei': 'hahahahahah'}

冰冻集合(frozen set)

  • 特殊集合,不可进行任何修改
# 创建
s = frozenset()
print(type(s))
print(s)

你可能感兴趣的:(Python)