列表——list

假设一种场景,想要存班里所有同学的名字,那应该拿什么存呢?

我们可以拿一个字符串去存,例如:

stus = "s1,s2,s3,s4,s5……sn"

那我们要从里面把某一个学生取出来,或者说,想要统计班级内有多少学生,这种方式可以是可以,但是未免太麻烦,假设被别人看见你这么写,就可以卷铺盖回家了;为了里面我们被卷铺盖回家,我们可以怎么做?

答案是用: list(列表)

比如说:

stus = ['s1','s2','s3','s4',……,'sn',]

定义一个数组很简单,中括号内,每一个元素用逗号隔开 ,里面元素的类型不一定要一致,可以为 int ,也可以为 str 类型,下标从 0 开始。

定义一个空列表,有两种方式:

stus = []
stus = list()

那么我们这一个 list ,怎么对它进行操作,也就是增删改查呢?

  append、insert

stus.append('鲁班')     #在 list 的末尾增加一个元素
stus.insert(9,'程咬金')    #在指定的位置插入元素
stus.insert(999,'后羿')    #在指定的位置插入元素,假设位置不存在,那么默认把元素插入到最后

  list 都是从下标开始取值

print('单个取',stus[0])    # 第一个元素
print('最后一个元素',stus[-1])    # 最后一个元素
print('倒数第二个元素',stus[-2])    # 倒数第二个元素
print('改之前的',stus)    # 整个列表

  找到 list 的元素下标重新赋值

stus[4] = '马可波罗'  # 将下标为 4 的元素改成马可波罗

  但是,这里注意不要瞎赋值,假设赋值的下标超过最大值报错: IndexError: list assignment index out of range

  pop、del、remove

stus.pop(0)     # 删除指定位置的元素
stus.pop()     # 默认删除list里面最后一个元素
del stus[0]     # 删除指定的位置的元素
del stus    # 如果不跟下标,那么整个 list 会被删除
stus.remove("后羿")    # 删除指定的元素,如果 list 里面有多个一样的元素,那么就只会删掉一个(假设不知道下标,可用此方法)

  那么有个特殊情况,假设我们删除的下标不存在,或者说要移除的元素不存在,是会报错:ValueError: list.remove(x): x not in list;IndexError: pop index out of range

 其他常用方法

  我们根据场景来看一些方法

1、假设我们要判断一个 list 内某元素存不存在,或者说 list 内某元素的个数,用什么方法?

count = stus.count('程咬金')    # 某个元素在list里面的数量

2、把一个已经存在的 list 清空

stus.clear()     # 清空 list

3、将一个 list 重新复制一份

new_stus = stus.copy()    # 复制一个stus 列表,存为 new_stus

4、将 list 反转,第一个为最后一个,第二个为倒数第二个

stus.reverse()    # 反转
print(stus)

5、将 list 排序

nums = [9,23,12,234,23,5235,235,235,23523,523]
nums.sort()    # 从小到大升序排列
nums.sort(reverse=True) # 里面加个反转,也就是从大到小排列
print(nums)

6、将两个 list 拼接,有两个方式

stus.extend(nums) #把 nums 的元素,加入到 stus 里面
print(stus)

list3 = list1 + list2    # 将 list 1 和 list 2 拼接

7、要找出一个元素在 list 的下标,要注意,这里只是显示在 list 内的第一个下标,而且元素不存在是会报错的:ValueError: '程咬金' is not in list

result = stus.index('程咬金')    # 找某个元素的下标

8、判断一个元素是否在 list 内

if username not in usernames:
    print('username 不在 list 里面')
if username  in usernames:
    print('username 在 list 里面')

9、切片,假设有一个 list ,我们不同的步长打印出的结果也不一致,具体方式为:[::num](num 为所要打印的步长,为负数就逆向打印)

>>> shoplist = ['apple', 'mango', 'carrot', 'banana']
>>> shoplist[::1]
['apple', 'mango', 'carrot', 'banana']
>>> shoplist[::2]
['apple', 'carrot']
>>> shoplist[::3]
['apple', 'banana']
>>> shoplist[::-1]
['banana', 'carrot', 'mango', 'apple']

10、如何知道一个 list 的长度呢?

nums = [1,2,3,4,5]
len(nums)

11、切片

切片的作用就是按一定的规则从 list 内取出元素,比如说我们要取出一个 list 的后面 3 个元素,因为取下标只能一个一个取,如果我们想一次性取出来做一个 list ,有简单的方式就是切片

需要注意的是,切片顾头不顾尾,而且不只是 list ,有下标的都能切,比如说字符串

l = [1,2,3,4,5,6]
print(l[1:])    #从下标 1-最后一位
print(l[:])    #取整个 list
print(l[1:4])    #下标1-3位
print(l[::-1])    # 反向打印,如果步长为负数,那么取值的时候从右往左

小结:

  方法名  功能
 append  在末尾增加元素
 insert(1,'xxx')  在下标为 1 前插入 xxx
 stus[0]  list[下标]
 stus[4] = '马可波罗'  list[下标] =  新值
 pop(1)  删除下标为 1 的,不传值删除最后一位
 del stus[0]  删除下标为 0 的元素
 remove('xxx')  删除 list 内的 xxx
 常用方法   count('xxx')  查询 xxx 在 list 内的数量
 clear()  清空 list
 copy()  将 list 复制出来
 reverse()  将 list 反转
 sort()  将 list 排序
 extend()  list 拼接
 index('xxx')  找 xxx 元素的的下标
 in/not in  判断某元素是否在 list 内,返回布尔值
 [::num]  切片
 len(stus)  返回 list 的长度

多维数组

判断几个维度,看有几个中括号就 ok 了

nums1 = [1,2,3,4,5,['a','b','c','d']]    # 2 维数组
nums2 = [1,2,3,4,['a','b','c','d',['test','dev','pre']]] # 3 维数组

其实,我们的多维数组,也就是将子 list 看成是上一级 list 的一个元素而已

那假设我们要取 nums1 里面的 ‘c’,如何取?

print(nums1[5][2])

有趣的是,其实一个字符串也可以当成是一个 list 来看,比如说我们要取,nums2 list 里面的 dev 中的 'e' ,怎么取?

print(nums2[4][4][1][1])

练习

一、

  1. 用 list 存账号和密码
  2. 需要校验 用户不存在的话 要提示
  3. 需要校验是否为空
  4. 账号密码正确登录成功,提示当前日期
  5. 最多输错3次

解决方案:

  1. 输入账号密码
  2. 校验是否输入为空
  3. 校验账号是否存在 list.count()
  4. 从usernames里面找到user的下标,然后去password种去对应的密码
usernames = ['cwl','pn','gxn','hyp']
passwords = ['123456','abc123','324234','23423']

import datetime
today = datetime.datetime.today()
count = 0
# for i in range(4):
while count<3:
    count+=1
    username = input('username:').strip()#去掉一个字符串两边的空格
    password = input('password:').strip()
    if username=='' or password=='':
        print('账号/密码不能空!')
    # elif usernames.count(username)==0: #判断元素的个数
    elif username not in usernames: #判断元素是否存在某个list里面
        print('用户不存在!')
    else:
        user_index = usernames.index(username)#登录用户的下标
        p = passwords[user_index]#根据下标取到密码
        if password == p:#判断密码是否正确
            print('欢迎%s登录,今天的日期是%s.'%(username,today))
            break
        else:
            print('密码错误!')
else:
    print('错误次数已经用尽')

 注意:最后面的 else 是对应 for 循环的,当 for 循环正常全部执行完,那么就会去执行 else,可以发现我们的 for 循环内加了一个 break ,假设 for 循环被 break 住了,就不会去执行 else内的内容。这里再提一句 break 和 continue 的区别:

break 语句用于中断循环语句,也就是中止循环语句的执行,要注意的是:中断了 for 循环/while 循环,相应循环的 else 模块将不被执行

continue 语句是告诉 Python 跳过当前循环块中剩余的语句,并继续该循环的下一次迭代

 

二、写一个 sql 插入的语句,要求在 user 的 list 每个用户名字前面加上字母标志:bt-

复杂的方式1:取下标循环

stus = ['chengweiliang','chenqi','guoliwen']
password='123456'
index = 0
username=''
while index<len(stus):
    username = stus[index]
    username = 'szz-'+username
    sql='insert into user (username,password) value ("%s","%s");'%(username,password)
    print(sql)
    index+=1

复杂的方式2:

for i in range(len(stus)):  #b
    username = stus[i]
    print(username)
    sql='insert into user (username,password) value ("%s","%s");'%(username,password)

简单的方式(推荐):直接循环。for 循环直接循环一个 list ,就是取 list 里面的每一个元素

stus = ['chengweiliang','chenqi','guoliwen']
password = '123456'
for stu in stus:    # for循环直接循环一个 list,就是取 list 里面的每一个元素,这里的 stu 是随意命名的,直接用 i 也成,这个只是为了增强可读性
    print('每次循环取的值',stu)
    username = 'bt-'+stu
    print(username)
    sql='insert into user (username,password) value ("%s","%s");'%(username,password)

列表生成式

假设我们要有一个 list ,要将其变成一个两位的数数组(一位的前面补零),那么按照我们传统的方式来做就是:

l = []
for i in range(1,11)
    l.append(str(i).zfill(2))

那么有没有高级的做法?有的,叫列表生成式:

l2 = [str(i).zfill(2) for i in range(1,11)]

字典——dict

假设我们要存一个班级内学生的信息:用户名,密码,电话,住址……

那如果还用 list 来存,最好的方式就是做一个二维数组:

stus = [
           ['鲁班','123','1112','sdfsdf',[1,2,3,4] ],
           ['后裔','123','1112','sdfsdf',200,'北京'],
           ['程咬金','123','1112','sdfsdf',100],
           ['狄仁杰','123','1112','sdfsdf',200],
       ]

但这样看起来并不直观,而且取数很麻烦,那么更好的方式是什么呢?

字典的方式:以一种 key-value 键值对方式来存

字典是一种key-value的数据类 型,比如说要存每个人的信息,那么每个人的编号就是key,value就是每个人的信息,这样的话,一个字典就能存所有人的信息了。字典的定义使用{}, 大括号,每个值用“,”隔开,key和value使用“:”分隔

stu_info = {
    'username':'gzw',
    'password':'123456',
    'money':20,
    'addr':'广州'
}

为什么dict查找速度这么快?因为dict的实现原理和查字典是一样的。假设字典包含了1万个汉字,我们要查某一个字,一个办法是把字典从第一页往后翻,直到找到我们想要的字为止,这种方法就是在list中查找元素的方法,list越大,查找越慢。
第二种方法是先在字典的索引表里(比如部首表)查这个字对应的页码,然后直接翻到该页,找到这个字。无论找哪个字,这种查找速度都非常快,不会随着字典大小的增加而变慢,这种就是字典的实现方式。
字典的特性:
字典是无序的,因为它没有下标,用key来当索引,所以是无序的
字典的key必须是唯一的,因为它是通过key来进行索引的,所以key不能重复,天生就去重

那么我们来介绍一些字典的常用操作

新增字典

d1 = {} #创建空字典
d2 = dict() #创建空字典

d1['name'] = '后裔'
d1['age'] =  18
d1.setdefault('class','双子座')  # 这个增加的 key 是增加默认 key 值。如果使用 setdefault,key已经存在了,就不会修改原来key的值,setdefault 相当于一个初始化操作,不具备修改功能。如果这个key存在的话,那就不动它,不存在的话,添加一个
print('之前的',d1)

d2 = {'abc':1234}
d1.update(d2)    # 在 d1 字典内增加一个 d2 字典,更新字典值,如果key存在的话,就更新,不存在的话就添加
print(d1)

只有一种方式

d1['name']='甄姬'

print(d1['name'])  # 当 key 不存在时,会报错:KeyError
print(d1.get('money'))  # 当 key 不存在时,不会报错,返回一个 None
print(d1.get('money',0))    # 当 key 不存在,返回默认值为 0

print(d1.keys())     # 取到字典里面所有的key,存为一个 list
print(d1.values())     # 取到字典里面所有的value,存为一个 list

d1.pop('name')   # 删除 key 为 name
del d1['name']   # 删除 key 为 name 
d1.popitem()    # 随机删除一个 key
d1.clear()     # 清空整个字典

其他常用方法

1、打印所有的 key/value

print(d1.keys())     # 取到字典里面所有的key,存为一个 list
print(d1.values())     # 取到字典里面所有的value,存为一个 list

2、如果这个key存在的话,那就不动它,不存在的话,添加一个

d1.setdefault('class','双子座')

3、更新字典值,假设 key 存在,则直接更新 value,不存在 key ,则新增该 key-value

d2 = {'abc':1234}
d1.update(d2)    # 在 d1 字典内增加一个 d2 字典,更新字典值,如果key存在的话,就更新,不存在的话就添加

4、将字典转化成一个 list

print(dic.items())    # 字典转换成一个list

5、循环字典

dic = {'stu1':'cc','stu2':'andashu','stu3':'niuniu'}
for k in dic:
    print(k,dic[k])    # 打印key和value的值,推荐使用这种方式,速度快
for k,v in dic.items():
    print(k,v)    # 打印key和value的值,这种方式不推荐,因为会把字典转换成列表,效率不高

小结:

  方法 功能
新增字典 d1 = {} 新增空字典
d2 = dict() 新增空字典
d1.['key'] = 'value' 新增一对 key-value
d1.['key'] = 'new_value' 将 key 的值改为 new_value
d1['key'] 查 key 值对应的 value,key 值不存在会报错
d1.get['key'] 当 key 不存在时,返回 None
d1.pop('key') 删除 key
del d1['key'] 删除 key
d1.popitem() 随机删除一个 key
d1.clear() 清空整个字典
其他方法 print(d1.keys()) 以一个 list 形式打印所有 key 值
print(d1.values()) 以一个 list 形式打印所有 value 值
d1.setdefault('key','value') 如果 key 存在就不变,不存在就增加
d1.update(d2) 如果 key 存在就更新,不存在就增加
d1.items() 把字典转化成一个 list
for i in d1:print(i,dic[i]) 循环取值,其实就是取到 key
if key in d1:print(key 存在)

判断 key 是否存在

 

练习

一、

我们有一个 list ,里面存的是字典,现要求:

  1. 统计一下现有学生总共有多少金币
  2. 找出金币小于100的学生姓名
  3. 金币大于500的学生,扣去300金币,小于等于100的人,加上200金币
users = [
                {
                        "id": 2,
                        "name": "矿泉水",
                        "sex": "未知",
                        "age": 38,
                        "addr": "天通苑123",
                        "grade": "双子座123",
                        "phone": "12123654311",
                        "gold": 34000
                },
                {
                        "id": 8292,
                        "name": "矿泉水",
                        "sex": "未知",
                        "age": 38,
                        "addr": "天通苑",
                        "grade": "双子座",
                        "phone": "12123676705",
                        "gold": 100
                },
                {
                        "id": 8308,
                        "name": "矿泉水",
                        "sex": "未知",
                        "age": 38,
                        "addr": "天通苑",
                        "grade": "双子座",
                        "phone": "12123610039",
                        "gold": 100
                },
                {
                        "id": 8309,
                        "name": "矿泉水",
                        "sex": "未知",
                        "age": 38,
                        "addr": "天通苑",
                        "grade": "双子座",
                        "phone": "12123675980",
                        "gold": 100
                },
                {
                        "id": 8310,
                        "name": "矿泉水",
                        "sex": "未知",
                        "age": 38,
                        "addr": "天通苑",
                        "grade": "双子座",
                        "phone": "12123629672",
                        "gold": 100
                },
                {
                        "id": 8311,
                        "name": "矿泉水",
                        "sex": "未知",
                        "age": 38,
                        "addr": "天通苑",
                        "grade": "双子座",
                        "phone": "12123689607",
                        "gold": 100
                },
                {
                        "id": 8312,
                        "name": "矿泉水",
                        "sex": "未知",
                        "age": 38,
                        "addr": "天通苑",
                        "grade": "双子座",
                        "phone": "12123638612",
                        "gold": 100
                },
                {
                        "id": 8313,
                        "name": "矿泉水",
                        "sex": "未知",
                        "age": 38,
                        "addr": "天通苑",
                        "grade": "双子座",
                        "phone": "12123628322",
                        "gold": 100
                },
                {
                        "id": 8314,
                        "name": "矿泉水",
                        "sex": "未知",
                        "age": 38,
                        "addr": "天通苑",
                        "grade": "双子座",
                        "phone": "12123663283",
                        "gold": 100
                },
                {
                        "id": 8315,
                        "name": "矿泉水",
                        "sex": "未知",
                        "age": 38,
                        "addr": "天通苑",
                        "grade": "双子座",
                        "phone": "12123634676",
                        "gold": 100
                },
                {
                        "id": 8316,
                        "name": "矿泉水",
                        "sex": "未知",
                        "age": 38,
                        "addr": "天通苑",
                        "grade": "双子座",
                        "phone": "12123680540",
                        "gold": 100
                },
                {
                        "id": 9909,
                        "name": "矿泉水",
                        "sex": "",
                        "age": 15,
                        "addr": "中国湖南",
                        "grade": "双子座",
                        "phone": "12345679999",
                        "gold": 100
                },
                {
                        "id": 10277,
                        "name": "矿泉水",
                        "sex": "",
                        "age": 18,
                        "addr": "北京市昌平区",
                        "grade": "双子座",
                        "phone": "15249211246",
                        "gold": 100
                }
        ]
user

相关文章: