Python疫起学习·万丈高楼平地起Day07(精简版|浓缩就是精华)集合、程序控制结构知识点附上鸡兔同笼问题以及时间库终结

二十一、集合

集合set属于Python无序可变序列。集合是使用大括号括起来的各种数据,可以看作没有Value的字典。集合里面的元素不能重复。集合中只能包含数字、字符串、元组等不可变类型(或者说是可哈希)的数据,不能包含列表、字典、集合等可变类型数据

由于集合与字典一样,里面的值没有顺序,因此使用集合来去重是有代价的,代价就是原来列表的顺序也会被改变。

  • 集合对象的创建与删除
    可以使用set()函数将列表、元组、字符串、range对象等其他可迭代对象转换为集合
    在这里插入图片描述
    除了列表推导式、生成器推导式、字典推导式外,还有集合推导式
    在这里插入图片描述
  • 集合操作与运算
    • 1、集合元素增加与删除
      add()方法可以增加新元素,update()方法合并另外一个集合中的元素到当前集合中,并自动去重
      在这里插入图片描述
      集合对象的pop()方法随机删除并返回集合中的一个元素,如果集合为空则抛出异常;remove()方法删除集合中的元素,如果指定元素不存在则抛出异常;discard()方法从集合中删除一个特定元素,如果元素不存在则忽略该操作,所以总的来说discard()方法要安全一些;clear()方法清空集合
      在这里插入图片描述
    • 2、集合运算
      在这里插入图片描述
      在这里插入图片描述
      在这里插入图片描述
  • 不可变集合frozenset
    与set不同的地方在于没有提供add()、remove()等可以修改集合对象的方法,但支持交集、并集等运算
    在这里插入图片描述
  • 集合应用案例
    字典和集合都使用hash表来存储元素,元素查找速度非常快
import random 
import time

x1 = list(range(10000))
x2 = tuple(range(10000))
x3 = set(range(10000))
x4 = dict(zip(range(10000), range(10000)))
r = random.randint(0, 9999)

for t in (x4, x3, x2, x1):
    start = time.time()
    for i in range(9999999):
        r in t
    print(type(t), 'time used:', time.time() - start)

在这里插入图片描述
集合可以简化很多代码量,e.g.
在这里插入图片描述
等价于

newSet = set(listRandom)

再来个例子,得到指定范围内一定数量的不重复数字
在这里插入图片描述
等价于
在这里插入图片描述
利用字典和集合模拟有向图结构

def getDegrees(orientedGraph, node):
    outDegree = len(orientedGraph.get(node, []))
    inDegree = sum(1 for v in orientedGraph.values() if node in v)
    return (inDegree, outDegree)

graph = {'a' : set('bcdef'), 'b' : set('ce'), 'c' : set('d'), 'd' : set('e'), 'e' : set('f'), 'f' : set('cgh'), 'g' : set('fhi'), 'h' : set('fgi'), 'i' : set()}

print(getDegrees(graph, 'h'))

在这里插入图片描述
答案是(2,3)

  • 序列解包多种形式和用法
    序列解包就是让等号左右部分数目一样,把右边的内容同时赋值给左边
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    序列解包的逆运算:
    在这里插入图片描述

二十二、程序控制结构

  • 条件表达式
    存在短路效应(可提高程序运行效率)
    (1)在使用and连接的多个表达式中,只要有一个表达式不为真,那么后面的表达式就不会执行。(2)在使用or连接的多个表达式中,只要有一个表达式为真,那么后面的表达式就不会执行。
    在这里插入图片描述
    上述代码等价于
def Join(chList, sep = ','):
    return sep.join(chList)
Join(chList)
  • 选择结构:单分支结构、双分支结构、多分支结构、嵌套分支结构
x = input('Input two numbers:')
a, b = map(int, x.split())    #序列解包
if a > b:
    a, b = b, a
print(a, b)

解决鸡兔同笼问题
在这里插入图片描述
C语言有三目运算符,例如a > b ? a : b
那么Python也有一个三元运算符,语法为value1 if condition else value2,如果condition为真,则执行value1,反之执行value2

对于多重条件选择判断,需要使用“if…elif…else…”。其中,“elif”可以有0个,也可以有多个,但是else只能有0个或者1个。

使用字典实现多重条件控制
在这里插入图片描述
在这里插入图片描述
嵌套结构要注意代码缩进,因为这决定不同代码的从属关系

构建跳转表实现多分支选择结构
在这里插入图片描述

  • 循环结构

特别注意:在循环里面还有循环(循环嵌套)的时候,continue和break都只对自己所在的这一层循环有效,不会影响外面的循环。

循环代码优化技巧:尽量减少内层代码中的不必要计算,尽量引用局部变量,因为局部变量的查询和访问速度比全局变量略快

代码优化涉及的内容广泛:例如,如果经常需要测试一个序列是否包含一个元素就尽量使用字典或集合而不是用字典;把多个字符串连接成一个字符串时应尽量使用join()方法而不要使用运算符+;对列表进行元素插入或删除操作时应尽量从列表尾部进行…

对时间库的了结

拥有一款中国日历:

from datetime import date

daysOfMonth = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]

def myCalendar(year, month):
    start = date(year, month, 1).timetuple().tm_wday   #获取year年month月1日是第几周
    print('{0}年{1}月日历'.format(year, month).center(56))
    print('日\t一\t二\t三\t四\t五\t六')
    day = daysOfMonth[month - 1]
    if month == 2:
        if year % 400 == 0 or (year % 4 == 0 and year % 100 != 0):
            day += 1
            
    result = [' ' * 8 for i in range(start + 1)]
    result += list(map(lambda d : str(d).ljust(8), range(1, day + 1)))
    
    for i, day in enumerate(result):
        if i != 0 and i % 7 == 0:
            print()
        print(day, end = '')
    print()
    
def main(year, month = -1):
    if type(year) != int or year < 1000 or year > 10000:
        print('Year error')
        return 
    if type(month) == int:
        if month == -1:       #如果没有指定月份,就打印全年的日历
            for m in range(1, 13):
                myCalendar(year, m)
        elif month in range(1, 13):
            myCalendar(year, month)
        else:
            print('Month error')
            return 
    else:
        print('Month error')
        return 
    
    
main(2020)

运行部分效果如下,快来试试吧
在这里插入图片描述

如果喜欢我的文章,请记得一键三连哦,点赞关注收藏,你的每一个赞每一份关注每一次收藏都将是我前进路上的无限动力 !!!↖(▔▽▔)↗感谢支持,明天我们不见不散!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值