第八篇基本数据类型之列表、元组与字典

列表

写在最前,必须要会的:append(),extend(),insert(),索引,切片,循环

list  是一个类,是个对象

列表用 方括号[]括起来的,[]内以逗号分割每个元素,列表中的元素可以是数字,字符串,列表,布尔值,字典,元组,列表里想放什么都可以

列表的特点:

1. 列表是有顺序的;

2. 列表的元素可以被修改

对象.方法(): 某对象调用某方法,举例如下:专业术语应该是:li对象调用append方法

li = [1,2,3]
li.append(4)
print(li)

#结果
[1,2,3,4]

创建列表

li = [1,2,3,"age","alex"]   # 通过list类创建的对象 li

列表也是可以嵌套的

li = [1,2,3,"age","alex",[“name”,"age"]]   #  li有6个元素

获取列表内的元素:

1. 通过索引取值

print(li[0])

#结果
1
# 列表可以通过索引多层次一层一层的往下找,
li = [1,2,3,"age","alex",["shimeihua",[19, 20]],["name","age"]]   #  li有6个元素
print(li[5][1][0])

#结果
19

2. 通过切片取值

print(li[3:-1])

#结果
['age', 'alex']

3. for 、while循环获取列表元素

li = [1,2,3,"age","alex",["name","age"]]  

for item in li:
    print(item)

字符串一旦被创建,在内存里是连续着的,是不可以被修改的,若要修改,就会重新开辟一块内存存储;

而列表在内存可以是不连续的,是链表的存储方式,列表的元素是可以被修改的

li = [1,2,3,"age","alex",["name","age"]]   #  li有6个元素
li[1] = [4,5,6]
print(li)

#结果
[1, [4, 5, 6], 3, 'age', 'alex', ['name', 'age']]
li = [1,2,3,"age","alex",["name","age"]]   #  li有6个元素
li[1:3] = [120 ,90]

print(li)

#结果
[1, 120, 90, 'age', 'alex', ['name', 'age']]
# 上面展示了列表创建后可以被修改
# 下面的示例展示字符串创建后不可被修改

s = "hello world"
s[0] = "y"

print(s)

#结果
    s[0] = "y"
TypeError: 'str' object does not support item assignment

删除列表元素

pop()、remove()、clear() 是列表对象的内置方法

(1) 通过del 方法删除

li = [1,2,3,"age","alex",["name","age"]]   #  li有6个元素
li[1] = [4,5,6]


del li[1]  # 删除下标为1的元素
print(li)

(2)通过切片的方式删除

li = [1,2,3,"age","alex",["name","age"]]   #  li有6个元素

del li[1:4]  # 删除下表为1的元素
print(li)

#结果
[1, 'alex', ['name', 'age']]

(3)clear():清空列表 

li = ["age","alex"]
li.clear()
print(li)

#结果
[]

(4)pop(self, index=None):删除列表的元素,如果没有指定索引,默认删除列表的最后一个值;如果index传入了其他值,就可以指定删除对应索引的值
pop()方法删除的值,是可以获取到的,也就是可以有其他变量接受该删掉的值

li = ["age","alex",23,45,1,2,45,42,45,"age"]
v = li.pop()
v1 = li.pop(1)  # 指定需要删除的索引位置的值

print(li)
# 结果
['age', 23, 45, 1, 2, 45, 42, 45]

print(v) # 结果 age print(v1) alex

(5)remove(self, value):删除列表中的指定值,而且必须指定需要删除的元素,如果列表有多个相同的值,默认删除最左边的值

li = ["age","alex",23,45,1,2,45,42,45,"age"]
li.remove(45)
print(li)

#结果
['age', 'alex', 23, 1, 2, 45, 42, 45, 'age']

判断某元素是否在列表内

1. in 操作(字符串判断某字符是否在字符串内,也用in)

li = [1,2,3,"age","alex",["name","age"]]   #  li有6个元素
v = "alex" in li
print(v)

#在列表中的元素以逗号分割作为一个整体的,name是在第6个元素的列表里的,所以是FALSE
v1 = "name" in li
print(v1)

v3 = "ag"
print(v3)

#结果
True
False
False

将字符串转换成列表,字符串里的每个单个字符会被拿出来当做列表的一个元素

对于字符串,如果想转换列表,list(字符串),内部其实使用的for循环

a = "123nihaoma[1224]"
list1 = list(a)
print(list1)

#结果
['1', '2', '3', 'n', 'i', 'h', 'a', 'o', 'm', 'a', '[', '1', '2', '2', '4', ']']

数字可以转换成列表吗?

首先数字是不可以进行for循环的,所以不能转换为列表

a = 123
for i in a:
    print(i)

print(list(a))


#结果,错误结果是相同的
TypeError: 'int' object is not iterable

将列表转换成字符串:

1. 自己写for循环,一个一个处理。

前提条件,列表里既有数字又有字符串

li = [1,2,3,"age","alex",["shimeihua",[19, 20]],["name","age"]]   
s = ""
for i in li:
    s = s + str(i)

print(s)
print(type(s))

# 结果
123agealex['shimeihua', [19, 20]]['name', 'age']
<class 'str'>

2. 如果列表里只有字符串,可以有简便的转换方法,直接使用字符串的join()方法

#
# # 列表可以通过索引多层次一层一层的往下找,
li = ["age","alex","shimeihua","name","age"]  #  li有6个元素

v = "".join(li)
print(v)

#结果
agealexshimeihuanameage

列表的内置方法

(1)append(self, p_object):追加到列表的最后,必须要传一个参数,在原来值的最后追加,追加的值可以是数字,字符串,列表,字典等

li = ["age","alex"] 
li.append(5)
li.append("nihao")
li.append({"name":34})
print(li)

#结果
['age', 'alex', 5, 'nihao', {'name': 34}]

(2)copy():拷贝,浅拷贝,顾名思义,就是将原来的值复制一份,当然就需要有个新的变量来接受复制的值

li = ["age","alex"]
v = li.copy()
print(v)

#结果
['age', 'alex']

(3)count(self, value):计算列表里某个元素出现的次数。

关于方法里参数是否必填的问题,举例,count(self,value)里的value是比填的,举个生活中的例子,跟女票去办结婚证,身份证,结婚照是必带的,你不带,民政局小姐姐可给你办不了,即使你再帅也不行。

还有另一种默认参数,参数有默认值,你对该参数传了这值,就用你传的值,你没传值,就使用默认值,比如下面的index()方法。

li = ["age","alex",23,45,1,2,45,42,45,"age"]
v = li.count(45)
v1 = li.count("age")
print(v)
print(v1)

#结果
3
2

(4)extend(self, iterable):扩展原来的列表,它的参数必须是可迭代对象,将传入的值进行循环,然后每次循环取到的值加到列表的后面

iterable,是可迭代对象。

下面示例代码的每一次打印都是注销掉其他方法后进行的打印

li = ["age","alex",23,45,1,2,45,42,45,"age"]
# extend是将传入的没一个值进行循环,然后每次循环取到的值加到列表的后面
li.extend([9898,"不可怜"])
print(li)
# 结果
['age', 'alex', 23, 45, 1, 2, 45, 42, 45, 'age', 9898, '不可怜']

li.extend("ni好的")
print(li)
# 结果
['age', 'alex', 23, 45, 1, 2, 45, 42, 45, 'age', 'n', 'i', '', '']

# append是将传入的值作为一个整体追加到列表的后面
li.append([9898,"不可怜"])
print(li)
# 结果
['age', 'alex', 23, 45, 1, 2, 45, 42, 45, 'age', [9898, '不可怜']]

li.append("ni好的")
print(li)
# 结果
['age', 'alex', 23, 45, 1, 2, 45, 42, 45, 'age', 'ni好的']

(5)index(self, value, start=None, stop=None):找某个值的索引位置。

start:指定开始寻找的索引位置,stop:指定结束寻找的索引位置

li = ["age","alex",23,45,1,2,45,42,45,"age"]
v = li.index("alex")
v1 = li.index(45)  # 从左往右,找到第一个值即停止寻找
v2 = li.index(45,4,-1)

print(v)
print(v1)
print(v2)

#结果
1
3
6

(6)insert(self, index, p_object) :在指定索引位置往列表里插入元素,需要传入两个参数

index:指定需要插入值的索引位置,

p_object:插入的具体元素

li = ["age","alex",23,45,1,2,45,42,45,"age"]
li.insert(0,"my name")
print(li)

#结果
['my name', 'age', 'alex', 23, 45, 1, 2, 45, 42, 45, 'age']

(7)reverse():将当前列表进行翻转

li = ["age1","alex",23,45,1,2,45,42,45,"age2"]
li.reverse()
print(li)

#结果
['age2', 45, 42, 45, 2, 1, 45, 23, 'alex', 'age1']

(8)sort(self, key=None, reverse=False):对列表进行排序

默认是从小到大进行排序

指定参数reverse = True时,从大到小排序

# 欠,key参数后面补充

li = [23,45,1,2,45,42,45]
# 默认是从小到大进行排序
li.sort()
print(li)

#结果
[1, 2, 23, 42, 45, 45, 45]

# 如果要从大到小排序,需指定参数reverse = True
li = [23,45,1,2,45,42,45]
li.sort(reverse=True)
print(li)

#结果
[45, 45, 45, 42, 23, 2, 1]

元组

 创建元组,通过()创建。创建元组的时候可以在最后一个元素的后面再加一个逗号,逗号后面是没元素的,长度也不会变,还能方便以后查看代码,一眼就能认出这是元组,

当然也可以不加,推进是加个逗号。

而参数也是用()表示的,但是参数后面加逗号,就会报错

tu = (12,34,(45,5,6),["test",45],True,{"name":"age"},)

print(tu)

# 结果
(12, 34, (45, 5, 6), ['test', 45], True, {'name': 'age'})

元组的元素:可以是数字,元组,字符串,列表,布尔值,字典

tu = (12,34,(45,5,6),["test",45],True,{"name":"age"})

print(tu)

# 结果
(12, 34, (45, 5, 6), ['test', 45], True, {'name': 'age'})

元组的特点:

1. 一级元素不可被修改,不能增加或者修改 或者删除

tu = (111,222,333,444)
print(tu)

#结果
 (111,222,333,444)

元组的取值

通过索引取值

tu = (12,34,(45,5,6),["test",45],True,{"name":"age"},)

print(tu[1])
#结果
34

元组也可以切片

tu = (12,34,(45,5,6),["test",45],True,{"name":"age"},)

print(tu[1:5])
#结果
(34, (45, 5, 6), ['test', 45], True)

元组也可以进行循环,所以元组是可迭代对象

既然元组也是可迭代对象,那上面列表有个方法extend()的参数也可以是一个元组了。

tu = (12,34,(45,5,6),["test",45],True,{"name":"age"},)

for item in tu:
    print(item)

#结果
12
34
(45, 5, 6)
['test', 45]
True
{'name': 'age'}

列表,字符串,元组可以互相转换

tu = (12,34,(45,5,6),["test",45],True,{"name":"age"},)
str1 = "hello world"
list1 = [123,345,"age"]

# 字符串转换成列表
print(list(str1))
#结果
['h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd']

# 字符串转换成元组
print(tuple(str1))
# 结果
 ('h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd')

# 列表转换成字符串
print(type(str(list1)))
print(str(list1))
# 结果
<class 'str'>
[123, 345, 'age']

# 列表转换成元组
print(tuple(list1))
#结果
(123, 345, 'age')

#元组转换成字符串
print(type(str(tu)))
print(str(tu))
#结果
<class 'str'>
(12, 34, (45, 5, 6), ['test', 45], True, {'name': 'age'})

#元组转换成列表
print(list(tu))
# 结果
[12, 34, (45, 5, 6), ['test', 45], True, {'name': 'age'}]

连接元组内元素

(1)当元祖内的元素都是字符串的是,可以通过join()方法连接

tu = ("age","name","weight",)
v = "__".join(tu)
print(v)

# 结果
age__name__weight

(2)当元祖内含有其他类型的元素时,比如数字,只能自己写for循环进行连接了。

元组是有序的,所以可用通过索引就可以取到索引的元素

tu = ("age","name","weight",[(33,44)],)

# 取出33
print(tu[3][0][0])

元组的一级元素不可修改,但是元组一级元素里面的二级元素如果是列表等类型的时候则是可以修改的

tu = ("age","name","weight",[(33,44)],)

# tu元组的第4个元素是一个列表,这个列表就是tu元组的一级元素,所以这列表不可以被修改成其他类型,比如修改成字符串,是不能成功的;
# 但是[(33,44)]里的(33,44)则是列表的一级元素,可以被整体修改的

tu[3][0] = "modify"
print(tu)

#结果
('age', 'name', 'weight', ['modify'])

元组的内置方法

count(self, value):计算元组里的元素出现的次数

tu = ("age","name","weight",[(33,44)],)

print(tu.count("age"))
# 结果
1

index(self, value, start=None, stop=None):指定元素出现的索引文字

tu = ("age","name","weight",[(33,44)],)

print(tu.index("weight"))
# 结果
2

字典

写在最前,字典必须要会的几个方法:keys(), values(), items() ,get(), update(),for循环,索引,in 操作

 创建字典对象,由 { } 标识

info = {"key1":"value1",  #键值对
            "key2":"value2",
}            

字典的键可以是什么类型?

字典在保存到时候是以哈希表的方式保存的,是key是转换成哈希值的

列表,字典是不可以作为键的

布尔值是可以做为键的,True = 1 , FALSE = 0 ,但是要注意,字典的两个key如果一样,值只会随机取其中一个

info = {
    1:"asdf",
    "k1": "nihao",
    (2, 5): 234,    # 元组可以作为键
    Ture:"123",   # 布尔值,不可以作为键
    # [1,2]:123,    # 列表也不可以作为键
}

# 本例中,key 为 1 和 key 为 True 其实是相同的
print(info)

字典的值可以是什么类型?

字典的value可以是任何值

dic = {
    "k1":18,
    "k1":True,
    "k1":[11,22,33,44],
    "k1":{"kk1":"vv1",
          "kk2":"vv2"},
    "k1":(12,"lest")
}

字典是无序的,每次打印你都不会确定他的打印顺序

字典是无序的,那怎么获取字典的确定的值呢?

虽然字典是无序的,但是字典是我们定义的,相当于key是不变的,所以取值,可以通过key拿到值;

又因为字典是无序的,所以是无法通过切片的方式取到元素

info = {
    1:"asdf",
    "k1": "nihao",
    (2, 5): 234,    # 元组可以作为键
}

print(info[1],info["k1"])

# 结果
asdf nihao

 通过键+索引可以一层层的查到到指定元素的值

info = {
    1:"asdf",
    "k1": "nihao",
    (2, 5): 234,    # 元组可以作为键
    "k3":[
        11,[],(),22,{"kk1":"vv1","kk2":"vv2","kk3":(11,22)}
    ]
}

# 需求取出kk3对应的值里的11
print(info["k3"][4]["kk3"][0])

删除字典元素

(1)通过del删除

info = {
    1:"asdf",
    "k1": "nihao",
    (2, 5): 234,    # 元组可以作为键
    "k3":[
        11,[],(),22,{"kk1":"vv1","kk2":"vv2","kk3":(11,22)}
    ]
}

del info["k1"]
print(info)

#结果
{1: 'asdf', (2, 5): 234, 'k3': [11, [], (), 22, {'kk1': 'vv1', 'kk2': 'vv2', 'kk3': (11, 22)}]}
info = {
    1:"asdf",
    "k1": "nihao",
    (2, 5): 234,    # 元组可以作为键
    "k3":[
        11,[],(),22,{"kk1":"vv1","kk2":"vv2","kk3":(11,22)}
    ]
}

# 需求:删除 kk1
del info["k3"][4]["kk1"]
print(info)
#结果
{1: 'asdf', 'k1': 'nihao', (2, 5): 234, 'k3': [11, [], (), 22, {'kk2': 'vv2', 'kk3': (11, 22)}]}

(2)pop(self, key, *args): 删除并获取值,pop可以删除指定键值对,如果制定键不存在,可以返回默认值

dic = {"k1":"v1",
       "k2": "v2",}

val = dic.pop("k1")
print(dic,"删除的值是:%s" % val)

# 要删除的键存在,如果设定了默认值,返回的值就是默认值
val1 = dic.pop("k1",90)
print(dic, "删除的值是:%s" % val1)

# 要删除的键不存在,返回的值就是指定的默认值
val2 = dic.pop("kkkk1",90)
print(dic, "删除的值是:%s" % val2)

# 结果
{'k2': 'v2'} 删除的值是:v1
{'k2': 'v2'} 删除的值是:90
{'k2': 'v2'} 删除的值是:90

(3)popitem():随机删除字典的键值对

dic = {"k1":"v1",
       "k2": "v2"}

k, v = dic.popitem()
print(dic,"删除的键是%s,值是%s" % (k,v))

#结果
{'k1': 'v1'} 删除的键是k2,值是v2

字典是没法使用while循环的。

字典的for循环:默认是根据 key 进行循环的

keys():获取字段的键

info = {
    1:"asdf",
    "k1": "nihao",
    (2, 5): 234,    # 元组可以作为键
    "k3":[
        11,[],(),22,{"kk1":"vv1","kk2":"vv2","kk3":(11,22)}
    ]
}

for item in info:
    print(item)

print("---------------------")
# 字典也提供了keys()方法获取字典的所有key for item1 in info.keys(): print(item1) # 结果 1 k1 (2, 5) k3 --------------------- 1 k1 (2, 5) k3

同理,for循环也可以循环value

values():获取字典的值

info = {
    1:"asdf",
    "k1": "nihao",
    (2, 5): 234,    # 元组可以作为键
    "k3":[
        11,[],(),22,{"kk1":"vv1","kk2":"vv2","kk3":(11,22)}
    ]
}

# 字典也提供了keys()方法获取字典的所有key
for item1 in info.values():
    print(item1)
    
# 结果
asdf
nihao
234
[11, [], (), 22, {'kk1': 'vv1', 'kk2': 'vv2', 'kk3': (11, 22)}]

for 循环同时拿到 key 和value:

items():同时拿到字典的键值对

info = {
    1:"asdf",
    "k1": "nihao",
    (2, 5): 234,    # 元组可以作为键
    "k3":[
        11,[],(),22,{"kk1":"vv1","kk2":"vv2","kk3":(11,22)}
    ]
}

# 字典也提供了keys()方法获取字典的所有key
for item in info:
    print(item,info[item])

print("------------------------")

# 当然,Python也很温柔的帮忙你想到了这个需求,并提供了items()方法
for k,v in info.items():
    print(k,v)

# 结果
1 asdf
k1 nihao
(2, 5) 234
k3 [11, [], (), 22, {'kk1': 'vv1', 'kk2': 'vv2', 'kk3': (11, 22)}]
------------------------
1 asdf
k1 nihao
(2, 5) 234
k3 [11, [], (), 22, {'kk1': 'vv1', 'kk2': 'vv2', 'kk3': (11, 22)}]

 字典内置的方法

clear():清空字典

copy(): 复制(浅拷贝)

fromkeys(*args, **kwargs):静态方法,这种方法的访问支持: 类名.方法名(),如 dict.fromkeys()

fromkeys()的参数代表万能参数。

fromkeys()的参数虽然是万能,但实际上只能传两个参数,第一个参数是个序列,代表键,第二个参数代表值,并且第一个参数的每个元素都是一个键,第二参数是每一个键的值。

即
根据序列创建字典,并指定统一的值

举例:

v = dict.fromkeys([123,"adb","99"]) # 没有传第二个代表值的参数,没有指定值,默认为None
print(v)

#结果
{123: None, 'adb': None, '99': None}  


v = dict.fromkeys([123,"adb","99"],123)   # 统一指定值为 123
print(v)

#结果
{123: 123, 'adb': 123, '99': 123}


v = dict.fromkeys([123,"adb","99"],[234,"fad",100])  # 统一指定值[234,"fad",100]
print(v)

#结果
{123: [234, 'fad', 100], 'adb': [234, 'fad', 100], '99': [234, 'fad', 100]}
 @staticmethod # known case
    def fromkeys(*args, **kwargs): # real signature unknown
        """ Returns a new dict with keys from iterable and values equal to value. """
        pass

fromkeys方法的定义是这样的, 

get():根据key获取值,key不存在时,可以指定默认值,如果没指定默认值,默认值就是None

通过索引的方式取值,存在风险,如果key不存在,程序会报错,但是get()就不存在这个问题,示例
info = {
    #1:"asdf",
    True: "123",
    "k1": "nihao",
    (2, 5): 234,    # 元组可以作为键
    "k3":[
        11,[],(),22,{"kk1":"vv1","kk2":"vv2","kk3":(11,22)}
    ]
}
v = info.get("k1")
print(v)

# get()方法,key不存在,返回None,程序不会报错
v = info.get("KKKKkkkkvvv")
print(v)

#结果
nihao
None

get()指定默认值

info = {
    #1:"asdf",
    True: "123",
    "k1": "nihao",
    (2, 5): 234,    # 元组可以作为键
    "k3":[
        11,[],(),22,{"kk1":"vv1","kk2":"vv2","kk3":(11,22)}
    ]
}
v = info.get("k1",11111)   # 如果key存在,就忽略后面指定的默认值
print(v)

v = info.get("kkkkkkkkk1" ,111111) # 如果key不存在,其值就取指定的默认值111111
print(v)

#结果
nihao
111111

 setdefault(self, k, d=None):设置值,但是如果已经存在键值,则不设置,并获取当前key对应的值;如果不存在,则设置值,并获取当前key对应的值

dic = {"k1":"v1",
       "k2": "v2"}

v = dic.setdefault("k1","123")
print(dic,v)

v1 = dic.setdefault("kjj1","123")
print(dic,v1)

#结果
{'k1': 'v1', 'k2': 'v2'} v1
{'k1': 'v1', 'k2': 'v2', 'kjj1': '123'} 123

update(self, E=None, **F):更新字典,已经存在的覆盖掉,不存在的,更新上去

dic = {"k1":"v1",
       "k2": "v2"}
dic.update({"k1":"11111","k3":123})
print(dic)

#结果
{'k1': '11111', 'k2': 'v2', 'k3': 123}

# update 还支持直接赋值的方式,只不过是python内部做了字典的转换
dic.update(k4 = 444, k5 = "666")
print(dic)
{'k1': '11111', 'k2': 'v2', 'k3': 123, 'k4': 444, 'k5': '666'}

 in 操作:

dic = {"k1" : "V1"}

v = "k1" in dic
print(v)

v1 = "V1" in dic.values()
print(v1)

v2 = "k1" in dic.values()
print(v2)

#结果
True
True
False

猜你喜欢

转载自www.cnblogs.com/victorm/p/9095054.html