2-4、5 随机数、列表、元组、冒泡排序

随机数

  • random模块
    import random
    
  • randint(a,b)返回[ a, b ] 之间的整数
    ranom.randint(0,9)
    
  • choice(seq)从非空序列的元素中随机挑选一个元素,比如random.choice(range(10)),从0到9中随机挑选一个整数。sequence(序列)
    random.choice(range(10))
    random.choice([1,3,5,7])
    
  • randrange([start], stop[,step])从指定范围内,按指定基数递增的集合中获取一个随机数,基数缺省值位1.
    random.randrange(1,7,2)
    
  • random.shuffle(list) -> None 就地打乱列表元素。
    list0 = list(range(10))
    print(list0)
    random.shuffle(list0)
    print(list0)
    
  • sample(population,k)从样本空间或总体(序列或者集合类型)中随机抽取k个不同的元素,返回一个新的列表
    • random.sample([‘a’,‘b’,‘c’,‘d’],2)
    • random.sample([‘a’,‘a’],2)
      random.sample(['a','b','c','d'],2)
      random.sample(list0,2)
      random.sample(['a','a'],2)
      

列表练习

求100内的素数(prime number)

  • 从2开始到自身的-1的数中找到一个能整除的=>从2开始到自身开平方的数中找到一个能整除的数
  • 一个合数一定可以分解成几个素数的乘积,也就是说,一个数如果能被一个素数整除就是合数
    pri = []
    for i in range(2,100):
        flag = False # 定义一个开关,开关打开表示这个数是合数
        # 判断这个数是不是素数
        end = int(i**0.5)
        for j in range(2,end+1):
            if i % j == 0:
                flag = True
                break
            
        if not flag:
            pri.append(i)
    

计算杨辉三角前6行(Pascal’s triangle)

在这里插入图片描述

  • 第n行有n项,n是正整数
  • 第n行数字之和位2**(n-1)
  • 只打印出杨辉三角的数字
    pascal = []
    line = 6
    for i in range(line):
        record = []
        num_top = 1
        num_end = 1
        for j in range(i+1):
            if j == 0 or j == i :
                num = 1
            else :
                num = pascal[i-1][j-1] + pascal[i-1][j]
            record.append(num)
        pascal.append(record)
    for i in pascal:
        print(i)
    

元组tuple

  • 一个有序的元素组成的集合
  • 使用小括号()表示
  • 元组是不可变对象

元组的定义 初始化

  • 定义
    • tuple() -> empty tuple
    • tuple(iterable) -> tuple initialized from iterable’s items (initialized 初始化)
  • 示例
    工厂方法,一种抽象类的创建模式
    t = tuple() # 工厂方法
    print(t)#运行结果为:()
    t = ()
    print(t)#运行结果为:()
    t = tuple(range(1,7,2))#iterable
    print(t)#运行结果为:(1, 3, 5)
    t = (2,4,6,3,4,2)
    print(t)#运行结果为:(2, 4, 6, 3, 4, 2)
    t = (1,)# 一个元素元组的定义,注意有个逗号
    print(t)#运行结果为:(1,)
    t = (1,)*5
    print(t)#运行结果为:(1, 1, 1, 1, 1)
    t = (1,2,3)*6
    print(t)#运行结果为:(1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3)
    

元组其他操作

  • 元组是只读的,所以增、删、改都没有

元组查询

  • index(value,[start,[stop]])
    • 通过值value,从指定区间查找列表内的元素是否匹配
    • 匹配到第一个就立即返回索引
    • 匹配不到,抛出异常ValueError
  • count(value)
    • 返回列表中匹配value的次数
  • 时间复杂度
    • index和count方法都是O(n)
    • 随着列表数据规模的增大,而效率下降
  • len(tuple)
    • 返回元素的个数

元组元素的访问

  • 支持索引(下标)
  • 正索引:从左至右,从0开始,为列表中每一个元素编号
  • 负索引:从右至左,从-1开始
  • 正负索引不可以越界,否则引发异常IndexError
  • 元组通过索引访问
    • tuple[index],index就是索引,使用中括号访问

命名元组namedtuple

  • 帮助文档中,查阅namedtuple,有使用例程
  • namedtuple(tupel, field_names, verbose = False, rename = False)
    • 命名元组,返回一个元组的子类,并定义了字段
    • field_names可以是空白符或逗号分割的字段的字符串,可以是字段的列表
  • 示例
    from collections import namedtuple
    Point = namedtuple('_Point',['x','y'])#Point为返回的类
    p = Point(11,22)
    p#运行结果为:_Point(x=11, y=22)
    Student = namedtuple('Student','name age')
    tom = Student('tom',20)
    tom#运行结果为:Student(name='tom', age=20)
    jerry = Studnet('jerry',18)
    jerry#运行结果为:Student(name='jerry', age=18)
    print(tom.name,jerry.age)#运行结果为:tom 18
    tom.age = 100#运行抛出AttributeError
    

练习

  • 依次接收用户输入的3个数,排序后打印
    • 转换int,判断大小排序。使用分支结构完成。
      # num = [5,6,9]
      num = []
      for i in range(3) :
          mid = input()
          num.append(int(mid))
      sort_num = []
      if num[0] > num[1]:# 0 > 1
          if num[0] > num[2]:# max:0
              sort_num.append(0)
              if num[1] > num[2]:# 0 > 1 > 2
                  sort_num.append(1)
                  sort_num.append(2)
              else:# 0 > 2 > 1
                  sort_num.append(2)
                  sort_num.append(1)
          else : # max:1
              sort_num.append(1)
              if num[0] > num[2]:#1 > 0 > 2 
                  sort_num.append(0)
                  sort_num.append(2)
              else:#1 > 2 > 0
                  sort_num.append(2)
                  sort_num.append(0)
      else :# 1 > 0
          if num[1] > num[2]:# max:1
              sort_num.appen(1)
              if num[0] > num[2]:# 1 > 0 > 2 
                  sort_num.append(0)
                  sort_num.append(2)
              else:# 1 > 2 > 0
                  sort_num.append(2)
                  sort_num.append(0)
          else : # max:2
              sort_num.append(2)
              if num[0] > num[1]:
                  sort_num.append(0)
                  sort_num.append(1)
              else:
                  sort_num.append(1)
                  sort_num.append(0)
              
      for i in range(3) :
          print(num[sort_num[i]],end = " ")
      
    • 使用max函数
      #num = [98,28,48]
      num = []
      for i in range(3) :
          mid = input()
          num.append(int(mid))
      sort_num = []
      for i in range(3):
          rec = max(num)
          num.pop(num.index(rec))
          sort_num.append(rec)
          
      for i in range(3) :
          print(sort_num[i],end = " ")
      
    • 使用列表的sort方法
      num = []
      for i in range(3) :
          mid = input()
          num.append(int(mid))
          
      num.sort()
      for i in range(3) :
          print(num[i],end = " ")
      
    • 冒泡法
      #num = [98,28,48]
      num = []
      for i in range(3) :
          mid = input()
          num.append(int(mid))
       #冒泡排序
      for i in range(2) :
          for j in range(3-i-1):
              if num[j] > num[j+1]:
                  num[j],num[j+1] = num[j+1],num[j]
                  
      num
      

冒泡法

在这里插入图片描述

冒泡法

  • 属于交换排序
  • 两两比较大小,交换位置。如同水泡咕嘟咕嘟往上冒
  • 结果分为升序和降序排列

升序

  • n个数从左至右,编号从0开始到n-1,索引0和1的值比较,如果索引0大,则交换两者位置,如果索引1大,则不交换,继续比较索引1和2的值,将大值放在右侧。直至n-2和n-1比较完,第一轮比较完成。第二轮从索引0比较到n-2,因为最右侧n-1位置上已经是最大值了。以此类推,每一轮都会减少最右侧的不参与比较,直至剩下最后2个数比较。

降序

  • 和升序相反

冒泡法总结

  • 冒泡法需要数据一轮轮比较
  • 可以设定一个标记判断此轮是否有数据交换发生,如果没有发生交换,可以结束排序,如果发生交换,继续下一轮排序
  • 最差的排序情况是,初始顺序和目标顺序完全相反,遍历次数1,…,n-1之和n(n-1)/2
  • 最好的排序情况是,初始排序和目标顺序完全相同,遍历次数n-1
  • 时间复杂度O(n**2)
  • 改进版冒泡法代码
    #num = [98,28,48]
    num = []
    for i in range(5) :
        mid = input()
        num.append(int(mid))
    cou = len(num)
    for i in range(cou) :
        flag = False
        for j in range(cou-i-1):
            if num[j] > num[j+1]:
                num[j],num[j+1] = num[j+1],num[j]
                flag = True
        if not flag :
            break
    num
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值