python(二)——list、字典、字符串操作

列表——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

解决方案:

1、统计一下现有学生总共有多少金币

  1. 循环users这个list
  2. 从每个user的字典里面取到gold
  3. 把每次的gold值相加

2、找出金币小于100的学生姓名

  1. 循环users这个list
  2. 从每个user的字典里面取到gold
  3. 判断gold的值是否小于100

3、金币大于500的学生,扣去300金币,小于等于100的人,加上200金币

  1. 循环users这个list
  2. 从每个user的字典里面取到gold
all_gold = 0 #存放所有的金币
for user in users:
        gold = user.get('gold')
        all_gold = gold+all_gold
        # all_gold += user.get('gold')
        if gold<=100:
                print('%s的金币小于等于100'%user.get('name'))
                user['gold'] = gold+200
        if gold>500:
                user['gold'] = gold - 300
print(users)

 

二、

现在有一个 list ,把字典里面每个用户的密码,前面都加上 username_ +

users = {
    "gzw1":'123456sdf',
    "gzw2":'123456sd',
    "gzw3":'123456sdf',
    "gzw4":'1234sdf56',
    "gzw5":'12345gsdfs6',
    "gzw6":'1234324g56',
}

 

解决方案:

1、循环这个字典
2、把value修改成value = key_+value

方式1:

for k in users:#直接循环一个字典的话,循环的是key
    value = users[k] #通过key取到value
    users[k] = '%s_%s'%(k,value)
print(users)

方式2:转化成 list 操作

for k,v in users.items():
    print('%s===>%s'%(k,v))
    users[k] = '%s_%s' % (k, v)

 

三、

stus = {
    "胖妞":
        {
            "house": ['三环', "四环", "七环"],
            "car": {
                "日本": ["雷克萨斯", "英菲尼迪"],
                "中国": ['五菱宏光', '红旗', '比亚迪', "宝骏"],
                "美国": ["福特", "凯迪拉克"]
            },
            "化妆品": {
                "SK-2": 1000,
                "YSL": 8000
            }
        },
    "陆明":{
        "money":[1000,5000,8000,800000],
        "xifu":{
            "越南":2,
            "伊拉克":10,
            "韩国":2,
            "泰国":3
        }

    }
}

1、统计一下胖妞总共有多少辆车

car = stus['胖妞']['car']
# car.update(new_car)
all_count = 0
for c in car.values():
    all_count = len(c)+all_count
print('胖妞总共有%s辆车'%all_count)

2、胖妞又买了,德国车2辆,奥迪、奔驰

stus['胖妞']['car']['德国'] = ['奥迪''奔驰']

3、胖妞的化妆品全被男朋友扔了

suts[''胖妞].remove('化妆品')

4、胖妞买了套房子在四环

house = stus['胖妞']['house']
house.append('四环')

5、胖妞把比亚迪换成了保时捷

stus['胖妞']['car']['中国'][2] = '保时捷'

 

字符串处理

   字符串是不能修改的

定义一个字符串:

s = "  ab c   cc  c   "

users='abc,xiaozi,xiaobai,xiaohei,xiaoming,xiaolan'

li = ['abc', 'xiaozi', 'xiaobai', 'xiaohei', 'xiaoming', 'xiaolan']

s.strip() 去除字符串两边的空格,换行符
s.strip('c') 去掉字符串两边的字符 'c'
s.lstrip() 去除左边的空格以及换行符
s.rstrip() 去除右边的空格以及换行符
s.count('c') 字符串内字符 'c' 的个数
s.index('d') 字符串内第一个 'd' 的下标,不存在会报错
s.find('d') 字符串内第一个 'd' 的下标,不存在会返回 -1
s.capitalize() 首字母大写
s.upper() 全部变成大写
s.lower() 全部变成小写
s.replace("c","C") 将 'c' 替换为 'C',默认全局替换。可用于清除字符串内的空格以及换行
s.replace("c","C",1) 只替换第一个 'c',最后传的为个数
s.endswith('xxx') 判断是否以 'xxx' 为结尾,可用来判断上传文件的格式,返回布尔类型
s.startswith('xxx') 判断是否以 'xxx' 为开头,返回布尔类型
s.center(50,'*') 将 s 字符串扩充到 50 个字符,不够的话,左右用 * 号补齐,s 在最中间
s.isspace() 判断 s 是否为空格,如果为空,会返回 False
s.islower() 判断 s 是否为全小写,返回布尔类型
s.isupper() 判断 s 是否为全大写,返回布尔类型
s.isalnum() 判断 s 有无特殊符号:@#等;s 为数字或字母为 True
s.isalpha()  s 不是数字,特殊符号,就返回 True
s.isdigit()  s 为整数,返回 True
'1'.zfill(5) 将数字前面补 0 到 5 位
s.format() 格式化输出
s.format_map() 格式化输出,传的值为字典形式
users.split(',') 将 users 字符串用 ',' 分割;括号内不传值,默认用空格分开
','.join(li) 将 li 这个 list 转成字符串,用','连接

格式化输出

1、直接 + 号

2、用 %s 号占位符,注意参数的格式

username='abc'
today = '2019-03-30'
print( '欢迎%s登陆,今天的日期是%s.'%(username,today))

% 占位,不一定要加 s ,s 是代表 string ,还有其他用法,常见的:%d 和 %f ,%d 代表 digital - 整数;%f 代表 float - 浮点数小数

要注意的是:

%f 默认保留 6 位小数,也可指定位数,假设 %.2f 代表保留两位小数

%d 是默认只取整数位置,就比如说下面的例子,就算 age = 18.02822,打印出来也是 18

%d 和 %f 对应的参数类型必须为整数或者小数,假设 age = 'gzw',那么就会报错了

%s 就没有限制,什么都能打印出来,但是规范用法最好是根据数字类型来指定输出的类型

username = '小黑'
age = 18
high = 1.78
s1 = '欢迎 %s登录,它的年龄是 %d 它的身高是 %f '%(username,age,high)
print(s1)

3、format()

username='abc'
today = '2019-03-30'
print( '欢迎{}登陆,今天的日期是{}.'.format(username,today))

 更直观好看的:

s3="insert into user value ({username},{password},{phone})"
new_s3 = s3.format(password="123",username='abc',phone='110')
print(new_s3)

4、format_map(),用字典形式传值

s3="insert into user value ({username},{password},{phone})"
new_s3 = s3.format_map({"password":123,
                        'username':'ccc',
                        'phone':110
                        })
print(new_s3)

分割

假设有一个字符串:users='abc,xiaozi,xiaobai,xiaohei,xiaoming,xiaolan',每个逗号之间存的是用户名,假设我们要将其取出,每个名字之前加入'bt-',怎么弄?

将其变成一个 list 就好弄了,那么怎么弄呢?

result = users.split(',')
for use in users:
    use = 'bt-'+use

那么有个特殊情况,假设我们的分割符号不在字符串内,那么会将整个字符串作为一个 list ,也就是:['abc,xiaozi,xiaobai,xiaohei,xiaoming,xiaolan']

那么反过来咋办?一个 list 如何转化成一个字符串

li = ['abc', 'xiaozi', 'xiaobai', 'xiaohei', 'xiaoming', 'xiaolan']

list = ','.join(li)

元组

  元组很简单,元组是一种不可变的数组,理解为不可修改的 list,什么情况下被用到呢?假设我们要定义一个东西,不希望被修改,那么可以用元组来定义。比如说数据库的连接配置

添加

元组的定义方式:

t = ('127.0.0.1',3306,'root','123456')#元组

操作

既然元组不能被修改,那么它的可操作性也就少了很多,就是不能修改/删除,但是也可以循环取值等

t = ('127.0.0.1',3306,'root','123456')    # 元组
t.count(3306)    # 查找 3306 的个数
t.index(3306)    # 查找第一个 3306 的下标
print(t[1])    # 打印下标为 1 的元素

集合

  记住一点:集合天生可以去重,且无序!!!

定义一个集合

l = [1,2,3,3,4,4]
res = set(l)
print(res)

刚刚我们说过,集合天生去重,那么这里 print 出来的值应该为:

{1, 2, 3, 4}

那么,集合我们可以大概知道是啥,那么集合就有几个方法可以用,基本的取交集并集差集要会,还有一些奇葩的集:对称差集

交集

  交集很简单,假设 a、b 两个集合,交集 = a∩b,也就是取 a 和 b 共有重叠的那部分

s1 = {1,2,3,4}
s2 = {4,5,6,7}
print(s1.intersection(s2)) #取交集
print(s1 & s2) #取交集

并集

  并集就是 a 和 b 结合起来

s1 = {1,2,3,4}
s2 = {4,5,6,7}
print(s1.union(s2))
print(s1 | s2)

差集

  差集就是 b 里面除掉 a 和 b 都有的那部分

s1 = {1,2,3,4}
s2 = {4,5,6,7}
print(s2 - s1)     # s2 里面有,s1 里面没有的
print(s1.difference(s2))

对称差集

  对称差集,就是 a 和 b 的并集除去 a 和 b 的交集那部分

s1 = {1,2,3,4}
s2 = {4,5,6,7}
print(s1.symmetric_difference(s2))     # 把a和b里面都有的去掉
print(s1^s2)

集合操作

  集合是不重复且无序的,那么也就没什么下角标的说法,能操作的也比较简单,也可以做添加元素,也能循环。删除以及增加的功能如下:

s1 = {1,2,3,4}
s2 = {4,5,6,7}
s1.add('abc')
s1.remove('abc')
if 'abc' in s1:
    print('在集合内')

 

 练习

  要求输入内容必须包含大写字母、小写字母、数字、特殊字符

import string
password = input('请输入密码:').strip()
if password:
    print('输入不为空')
else:
    print('密码不能为空')
p_set = set(password)
print('大写字母取',p_set.intersection(set(string.ascii_uppercase)))
print('小写字母取',p_set.intersection(set(string.ascii_lowercase)))
print('数字取',p_set.intersection(set(string.digits)))
print('特殊字符取',p_set.intersection(set(string.punctuation)))
if p_set.intersection(set(string.ascii_uppercase)) and \
        p_set.intersection(set(string.ascii_lowercase)) \
    and p_set.intersection(set(string.digits)) \
        and p_set.intersection(set(string.punctuation)):
    print('密码合法')
else:
    print('密码必须包含大写字母、数字、特殊字符串')

 

作业

1、写一个注册的程序

  1. 注册的账号密码存在文件里面
  2. 密码不能为纯数字
  3. 已经存在的账号要提示该账号已经被注册
  4. 账号和密码长度要大于6小于13位
  5. 两次密码输入一致才可以
  6. 要校验输入不能为空
f = open('users.txt')
file_content = f.read()
f.close()
users = {}
if len(file_content)==0:
    pass
else:
    user_passwd_list = file_content.split('\n')
    for l in user_passwd_list:
        username = l.split(',')[0]
        passwd = l.split(',')[1]
        users[username] = passwd

for i in range(3):
    u = input('username:').strip()
    pwd = input('password:').strip()
    pwd2 = input('cpwd:').strip()
    if len(u)<6 or len(u)>13:
        print('用户名长度不合法')
    elif len(pwd)<6 or len(pwd)>13:
        print('密码长度不合法')
    elif pwd.isdigit():
        print('密码不能是纯数字')
    elif pwd!=pwd2:
        print('两次输入的密码不一致')
    elif u in users:
        print('用户已经被注册')
    else:
        users[u] = pwd
        print('注册成功!')
        break

f = open('users.txt','w')
for u,p in users.items():
    f.write('%s,%s\n'%(u,p))
f.close()

 

2、登录

  1. 账号密码从注册产生那个文件里面取
  2. 登录的时候账号大小写不区分
f = open('users.txt')
file_content = f.read()
f.close()
users = {}
if len(file_content)==0:
    pass
else:
    user_passwd_list = file_content.split('\n')
    for l in user_passwd_list:
        username = l.split(',')[0]
        passwd = l.split(',')[1]
        users[username] = passwd

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 username not in users:
        print('账号不存在!')
    elif password == users.get(username):
        print('登录成功!')
    else:
        print('账号/密码错误!')
else:
    print('错误次数已经用尽')

 

3、产生一批测试账号,存到文件里面

  1. 输入一个数字,就产生多少条
  2. 长度是10,账号包含字母和数字
  3. sdfs234sdf@163.com
  4. sdfs234sdf@163.com
  5. sdfs234sdf@163.com
import string
import random
num = input('number:').strip()
if not num.isdigit():
    print('请输入整数!')
else:
    file = open('account.txt','w')
    num = int(num)
    for i in range(num):
        t1 = random.sample(string.digits,5)
        t2 = random.sample(string.ascii_letters,5)
        result = ''.join(t1+t2)+'@163.com'+'\n'
        file.write(result)
    file.close()

 

posted @ 2019-04-09 20:44  小文叔  阅读(2238)  评论(0编辑  收藏  举报