列表List

函数

range()

可创建一个整数列表,一般用在 for 循环中。

返回:返回的是一个可迭代对象(类型是对象),而不是列表类型, 所以打印的时候不会打印列表,

1
range(start, stop,[step])

参数说明:

  • start: 计数从 start 开始。默认是从 0 开始。例如range(5)等价于range(0, 5);
  • top: 计数到 stop 结束,但不包括 stop。例如:range(0, 5) 是[0, 1, 2, 3, 4]没有5;
  • step:步长,默认为1。例如:range(0, 5) 等价于 range(0, 5, 1)
1
2
3
4
5
6
7
8
9
10
11
12
13
big_num =[]
for num in range(1,11):
num = num**2
big_num.append(num)
print(big_num)

返回
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

这个例子可以用列表解析进行简化
big_num =[num**2 for num in range(1,11)]
print(big_num)
返回 同

注意:range()并不直接创建一个数字列表,需要用函数list()将range()的结果转换为列表。

list()

ist() 函数用于将元组转换为列表。

注:元组与列表是非常类似的,区别在于元组的元素值不能修改的、是不可变的,元组是放在括号中,列表是放于方括号中。一般来说,不可变的列表叫元组。元组可以像列表一样通过索引来访问。

1
list( tuple )

参数说明:

  • tuple – 要转换为列表的元组。

返回:列表

1
2
3
4
5
num  = list(range(5))
print(num)

返回
[0, 1, 2, 3, 4]
1
2
3
4
5
num = list('word')
print(num)

返回
['w', 'o', 'r', 'd']
1
2
3
4
list1 = list('843613101')
print(list1)
输出
['8', '4', '3', '6', '1', '3', '1', '0', '1']
1
2
3
4
5
tuple = (1,2,3,4,3,4,5,6)
list1 = list(tuple)
print(list1)
输出
[1, 2, 3, 4, 3, 4, 5, 6]

min() max() sum()

数字列表执行简单的统计计算

括号内是列表

1
2
3
4
5
6
7
8
9
10
11
12
big_num =[]
for num in range(1,1000001):
big_num.append(num)

print(max(big_num))
print(min(big_num))
print(sum(big_num))

返回
1000000
1
500000500000

len()

统计列表中元素的个数,括号内是列表或元组

1
2
3
4
5
6
7
8
food =('a','b','c','d','e')
print(len(food))

food =['a','b','c','d','e']
print(len(food))

输出
5

dir()

1
2
3
4
5
list1 = ['a', 'b', 'c', 'teacher', 'school']
print(dir(list1))
输出
['__add__', '__class__', '__class_getitem__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']

enumerate()

通过enumerate处理后的列表在循环遍历时会返回取到一个二元组,解包之后第一个值是索引,第二个值是元素,下面是一个简单的对比。

1
2
3
4
5
6
7
8
9
list1 = list('843613101')
list2 = enumerate(list1)
print(list2)
list3 = list(enumerate(list1))
print(list3)

输出
<enumerate object at 0x000001EF1C6C8C80>
[(0, '8'), (1, '4'), (2, '3'), (3, '6'), (4, '1'), (5, '3'), (6, '1'), (7, '0'), (8, '1')]
1
2
3
4
5
6
7
items = ['Python', 'Java', 'Go', 'Swift']

for index in range(len(items)):
print(f'{index}: {items[index]}')

for index, item in enumerate(items):
print(f'{index}: {item}')

zip()

1
2
3
4
5
6
7
8
9
list1 = [1,23,4,5,6,7,8,9,0]
list2 = [4,5,6,7,8,5]
list3 = zip(list1,list2)
print(list3)
list4 = list(list3)
print(list4)
输出
<zip object at 0x0000013D9C478B40>
[(1, 4), (23, 5), (4, 6), (5, 7), (6, 8), (7, 5)]

方法

.count()

统计列表中某元素出现的次数,括号内是指定的某个元素

1
2
3
4
5
6
list = ['Python', 'Java', 'Java', 'Go', 'Kotlin', 'Python']

# 查找元素出现的次数
print(list.count('Python')) # 2
print(list.count('Go')) # 1
print(list.count('Swfit')) # 0

.append()

.append(obj)末尾添加一个

往列表的最后一个位置插入操作,括号内是插入的元素,但是只能添加一个元素进去,加两个就得报错,加两个得用extend()

返回:无,会修改列表。

1
2
3
num = ["a","b","c","school"]
num.append('love')
print(num)

.extend() 或 +相加

可以”+“号 来实现列表的相加。

1
2
3
4
5
6
7
num_1 = ["a","b","c"]
num_2 = ['teacher',"school"]
num = num_1 + num_2
print(num)

输出
['a', 'b', 'c', 'teacher', 'school']

.extend()末尾添加一列

列表A.extend(列表B)链接两个列表,将列表B接到A的最后边,形成一个新的列表A,A列表已经变化。也就是说extend可以添加两个以上的元素进去。注意,添加的方法:多个元素要放在方括号里,即extend()的参数是一个列表。

1
2
3
4
5
6
7
8
9
num_1 = ["a","b","c"]
num_2 = ['teacher',"school"]
num_1.extend(num_2)

num = num_1[:]
print(num)

输出
['a', 'b', 'c', 'teacher', 'school']
1
2
3
4
5
6
7
a = [ '1','2','3']
a.extend('4')
a.extend(['5','6'])
print(a)

输出
['1', '2', '3', '4', '5', '6']

注意 两个列表谨慎用 = 连接,一旦连接,两个列表作一个看。上边

1
num = num_1[:]

是把新的列表A复制一个副本给列表num。

.insert()

list.insert(index, obj),该方法用于将指定对象插入裂变的指定位置。

参数说明

  • index 索引
  • obj 对象,该对象可以是一个数字或字符串,也可以是一个列表的某一个索引值。但是,OBJ如果是列表,只能是列表的某一个索引“列表[2]“,如果把一段切片如列表[0,2],那么结果是把这一段切片带方括号插进指定位置了。说简单点,inset()只能插入一个,这一个还必须得是数字或字符串,列表也能插,只是就成了嵌套的。再简单点,只能插入一个,给啥插啥。

返回:无

1
2
3
4
5
6
7
8
9
10
num_1 = ['a', 'b', 'c', 'teacher', 'school']
num_1.insert(2,567)
print(num_1)
num_2 = ['i','love','U']
num_1.insert(2,num_2[0])
print(num_1)

输出
['a', 'b', 567, 'c', 'teacher', 'school']
['a', 'b', 'i', 567, 'c', 'teacher', 'school']
1
2
3
4
5
a = [ '1','2','3']
a.insert(1,['5','6'])
print(a)
输出
['1', ['5', '6'], '2', '3']

.pop()

.pop(index)

弹出列表中指定索引的元素并返回删除的元素,原列表将失去该元素。不指明索引,默认弹出最后一位。

在使用pop方法删除元素时,如果索引的值超出了范围,会引发IndexError异常,错误消息是:pop index out of range

1
2
3
4
5
6
7
8
num = ['a', 'b', 'c', 'teacher', 'school']
poped_num = num.pop()
print(num)
print(poped_num)

输出
['a', 'b', 'c', 'teacher']
school
1
2
3
4
5
6
7
num = ['a', 'b', 'c', 'teacher', 'school']
poped_num = num.pop(3)
print(num)
print(poped_num)
输出
['a', 'b', 'c', 'school']
teacher

.remove(obj)

list.remove(obj),移除列表中符合某个值得第一个匹配项

返回:无。没有返回值就不存在赋值。

在使用remove方法删除元素时,如果要删除的元素并不在列表中,会引发ValueError异常,错误消息是:list.remove(x): x not in list

del语句

del list[1]

使用Python中的del关键字后面跟要删除的元素,这种做法跟使用pop方法指定索引删除元素没有实质性的区别,但后者会返回删除的元素,前者在性能上略优

1
2
3
4
5
a = [ '1','2','3']
del a[1]
print(a)
输出
['1', '3']

del list 删除整个列表

1
2
3
4
5
a = [ '1','2','3']
del a
print(a)
输出
NameError: name 'a' is not defined

.sort()

**list.sort(cmp=None, key=None, reverse=False)**,默认升序

参数

cmp

key

reverse:翻转,reverse = True 降序, reverse = False升序(默认)

1
2
3
4
5
list1 = list('843613101')
list1.sort() #等同于list1.sort(reverse = False)
print(list1)
输出
['0', '1', '1', '1', '3', '3', '4', '6', '8']
1
2
3
4
5
list1 = list('843613101')
list1.sort(reverse = True) #等同于list1.reverse
print(list1)
输出
['8', '6', '4', '3', '3', '1', '1', '1', '0']
1
2
3
4
5
6
7
8
9
10
list = [(2, 2), (3, 4), (4, 1), (1, 3)]
# 获取列表的第二个元素
def takeSecond(elem):
return elem[1]
# 指定第二个元素排序
list.sort(key=takeSecond)
print(list)

输出
[(4, 1), (2, 2), (1, 3), (3, 4)]
1
2
3
4
5
6
list = ['a','bb','ccc']
list.sort(key = len)
print(list)

输出
['a', 'bb', 'ccc']
1
2
3
4
5
6
list = ['a','bb','ccc']
list.sort(key = len, reverse=True)
print(list)

输出
['ccc', 'bb', 'a']

2021年3月17日16:18:40

.reverse()

翻转列表

1
2
3
4
5
list1 = ['a', 'b', 'c', 'teacher', 'school']
list1.reverse()
print(list1)
输出
['school', 'teacher', 'c', 'b', 'a']

.index()

list.index(object,起始索引,结束索引):索引一下内容为object在列表中的位置,如果要确定在列表中某一个范围内的,需要指定范围。

1
2
3
4
list1 = ['a', 'b', 'c', 'teacher', 'school']
print(list1.index('school'))
输出
4
1
2
3
4
list1 = ['a', 'b', 'c', 'teacher', 'school','a', 'b', 'c', 'teacher', 'school','a', 'b', 'c', 'teacher', 'school']
print(list1.index('school',6,10))
输出
9

2021年3月23日13:54:53

列表的拷贝

注意 两个列表谨慎用 = 连接,一旦连接,两个列表作一个看。

真确操作:

1
list2 = list1[:]

是把列表1复制一个副本给列表2,同时并不影响列表1,修改列表2的同时列表1没变化。但是如果采用 list2 = list1 那就不一样了,视作同一个列表,修改列表2的同时列表1随之修改

索引

注意:由于列表是可变类型,所以通过索引操作既可以获取列表中的元素,也可以更新列表中的元素。对列表做索引操作一样要注意索引越界的问题,对于有N个元素的列表,正向索引的范围是0N-1,负向索引的范围是-1-N,如果超出这个范围,将引发IndexError异常,错误信息为:list index out of range

列表的生成式

在Python中,列表还可以通过一种特殊的字面量语法来创建,这种语法叫做生成式。我们给出两段代码,大家可以做一个对比,看看哪一种方式更加简单优雅。

通过for循环为空列表添加元素。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 创建一个由1到9的数字构成的列表
list1 = []
for x in range(1, 10):
list1.append(x)
print(list1)

# 创建一个由'hello world'中除空格和元音字母外的字符构成的列表
list2 = []
for x in 'hello world':
if x not in ' aeiou':
list2.append(x)
print(list2)

# 创建一个由个两个字符串中字符的笛卡尔积构成的列表
list3 = []
for x in 'ABC':
for y in '12':
list3.append(x + y)
print(list3)

通过生成式创建列表。

1
2
3
4
5
6
7
8
9
10
11
# 创建一个由1到9的数字构成的列表
list1 = [x for x in range(1, 10)]
print(list1) # [1, 2, 3, 4, 5, 6, 7, 8, 9]

# 创建一个由'hello world'中除空格和元音字母外的字符构成的列表
list2 = [x for x in 'hello world' if x not in ' aeiou']
print(list2) # ['h', 'l', 'l', 'w', 'r', 'l', 'd']

# 创建一个由个两个字符串中字符的笛卡尔积构成的列表
list3 = [x + y for x in 'ABC' for y in '12']
print(list3) # ['A1', 'A2', 'B1', 'B2', 'C1', 'C2']

下面这种方式不仅代码简单优雅,而且性能也优于上面使用for循环和append方法向空列表中追加元素的方式。可以简单跟大家交待下为什么生成式拥有更好的性能,那是因为Python解释器的字节码指令中有专门针对生成式的指令(LIST_APPEND指令);而for循环是通过方法调用(LOAD_METHODCALL_METHOD指令)的方式为列表添加元素,方法调用本身就是一个相对耗时的操作。对这一点不理解也没有关系,记住“强烈建议用生成式语法来创建列表”这个结论就可以了。

元组tuple

是一个不可改变的对象,这是它不同于列表的最大特殊之处,一旦创建就不可改变。可以说是戴上枷锁的列表。具有列表的基本操作方式。

注意一个元组中如果有两个元素,我们就称之为二元组;一个元组中如果五个元素,我们就称之为五元组。需要提醒大家注意的是,()表示空元组,但是如果元组中只有一个元素,需要加上一个逗号,否则()就不是代表元组的字面量语法,而是改变运算优先级的圆括号,所以('hello', )(100, )才是一元组,而('hello')(100)只是字符串和整数。

1
2
3
4
5
6
7
8
9
10
11
12
13
# 空元组
a = ()
print(type(a)) # <class 'tuple'>
# 不是元组
b = ('hello')
print(type(b)) # <class 'str'>
c = (100)
print(type(c)) # <class 'int'>
# 一元组
d = ('hello', )
print(type(d)) # <class 'tuple'>
e = (100, )
print(type(e)) # <class 'tuple'>

元组的应用场景

讲到这里,相信大家一定迫切的想知道元组有哪些应用场景,我们给大家举几个例子。

例子1:打包和解包操作。

当我们把多个用逗号分隔的值赋给一个变量时,多个值会打包成一个元组类型;当我们把一个元组赋值给多个变量时,元组会解包成多个值然后分别赋给对应的变量,如下面的代码所示。

1
2
3
4
5
6
# 打包
a = 1, 10, 100
print(type(a), a) # <class 'tuple'> (1, 10, 100)
# 解包
i, j, k = a
print(i, j, k) # 1 10 100

在解包时,如果解包出来的元素个数和变量个数不对应,会引发ValueError异常,错误信息为:too many values to unpack(解包的值太多)或not enough values to unpack(解包的值不足)。

1
2
3
a = 1, 10, 100, 1000
# i, j, k = a # ValueError: too many values to unpack (expected 3)
# i, j, k, l, m, n = a # ValueError: not enough values to unpack (expected 6, got 4)

有一种解决变量个数少于元素的个数方法,就是使用星号表达式,我们之前讲函数的可变参数时使用过星号表达式。有了星号表达式,我们就可以让一个变量接收多个值,代码如下所示。需要注意的是,用星号表达式修饰的变量会变成一个列表,列表中有0个或多个元素。还有在解包语法中,星号表达式只能出现一次。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
a = 1, 10, 100, 1000
i, j, *k = a
print(i, j, k) # 1 10 [100, 1000]
i, *j, k = a
print(i, j, k) # 1 [10, 100] 1000
*i, j, k = a
print(i, j, k) # [1, 10] 100 1000
*i, j = a
print(i, j) # [1, 10, 100] 1000
i, *j = a
print(i, j) # 1 [10, 100, 1000]
i, j, k, *l = a
print(i, j, k, l) # 1 10 100 [1000]
i, j, k, l, *m = a
print(i, j, k, l, m) # 1 10 100 1000 []

需要说明一点,解包语法对所有的序列都成立,这就意味着对字符串、列表以及我们之前讲到的range函数返回的范围序列都可以使用解包语法。大家可以尝试运行下面的代码,看看会出现怎样的结果。

1
2
3
4
5
6
a, b, *c = range(1, 10)
print(a, b, c)
a, b, c = [1, 10, 100]
print(a, b, c)
a, *b, c = 'hello'
print(a, b, c)

现在我们可以反过来思考一下函数的可变参数,可变参数其实就是将多个参数打包成了一个元组,可以通过下面的代码来证明这一点。

1
2
3
4
5
6
7
8
9
10
def add(*args):
print(type(args), args)
total = 0
for val in args:
total += val
return total


add(1, 10, 20) # <class 'tuple'> (1, 10, 20)
add(1, 2, 3, 4, 5) # <class 'tuple'> (1, 2, 3, 4, 5)

例子2:交换两个变量的值。

交换两个变量的值是编程语言中的一个经典案例,在很多编程语言中,交换两个变量的值都需要借助一个中间变量才能做到,如果不用中间变量就需要使用比较晦涩的位运算来实现。在Python中,交换两个变量ab的值只需要使用如下所示的代码。

1
a, b = b, a

同理,如果要将三个变量abc的值互换,即b赋给ac赋给ba赋给c,也可以如法炮制。

1
a, b, c = b, c, a

需要说明的是,上面并没有用到打包和解包语法,Python的字节码指令中有ROT_TWOROT_THREE这样的指令可以实现这个操作,效率是非常高的。但是如果有多于三个变量的值要依次互换,这个时候没有直接可用的字节码指令,执行的原理就是我们上面讲解的打包和解包操作。

例子3:让函数返回多个值。

有的时候一个函数执行完成后可能需要返回多个值,这个时候元组类型应该是比较方便的选择。例如,编写一个找出列表中最大值和最小的函数。

1
2
3
4
5
6
7
8
9
10
11
12
def find_max_and_min(items):
"""找出列表中最大和最小的元素
:param items: 列表
:return: 最大和最小元素构成的二元组
"""
max_one, min_one = items[0], items[0]
for item in items:
if item > max_one:
max_one = item
elif item < min_one:
min_one = item
return max_one, min_one

上面函数的return语句中有两个值,这两个值会组装成一个二元组然后返回。所以调用find_max_and_min函数会得到这个二元组,如果愿意也可以通过解包语法将二元组中的两个值分别赋给两个变量。

元组和列表的比较

这里还有一个非常值得探讨的问题,Python中已经有了列表类型,为什么还需要元组这样的类型呢?这个问题对于初学者来说似乎有点困难,不过没有关系,我们先抛出观点,大家可以一边学习一边慢慢体会。

  1. 元组是不可变类型,不可变类型更适合多线程环境,因为它降低了并发访问变量的同步化开销。关于这一点,我们会在后面讲解多线程的时候为大家详细论述。

  2. 元组是不可变类型,通常不可变类型在创建时间和占用空间上面都优于对应的可变类型。我们可以使用sys模块的getsizeof函数来检查保存相同元素的元组和列表各自占用了多少内存空间。我们也可以使用timeit模块的timeit函数来看看创建保存相同元素的元组和列表各自花费的时间,代码如下所示。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    import sys
    import timeit

    a = list(range(100000))
    b = tuple(range(100000))
    print(sys.getsizeof(a), sys.getsizeof(b)) # 900120 800056

    print(timeit.timeit('[1, 2, 3, 4, 5, 6, 7, 8, 9]'))
    print(timeit.timeit('(1, 2, 3, 4, 5, 6, 7, 8, 9)'))
  3. Python中的元组和列表是可以相互转换的,我们可以通过下面的代码来做到。

    1
    2
    3
    4
    5
    6
    # 将元组转换成列表
    info = ('骆昊', 175, True, '四川成都')
    print(list(info)) # ['骆昊', 175, True, '四川成都']
    # 将列表转换成元组
    fruits = ['apple', 'banana', 'orange']
    print(tuple(fruits)) # ('apple', 'banana', 'orange')

列表和元祖的经典案例

案例1:成绩表和平均分统计

说明:录入5个学生3门课程的考试成绩,计算每个学生的平均分和每门课的平均分。

我写的解决办法是

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
"""
录入5个学生3门课程的考试成绩
计算每个学生的平均分和每门课的平均分
"""
# students_name = ['张三','李四','王五','赵钱','孙俪']
# course = ['数学','语文','英语']

students_name = ['张三','李四']
course = ['数学','语文']

# 创建了一个储藏五个学生成绩的列表
scores = []
for x in range(len(students_name)):
scores.append([0]*len(course))
#收集数据
for i,x_name in enumerate(students_name) :
for j,y_course in enumerate(course):
score = input(f'请输入{x_name}{y_course}的成绩:')
scores[i][j] = int(score)
print(scores)
#计算每个学生的平均分

for i in range(len(students_name)):
name_total_score = 0
for j in range(len(course)):
name_total_score += scores[i][j]
pjcj = name_total_score/(len(course))
print(f"{students_name[i]}的平均成绩是:{pjcj}")

#计算每门课的平均分

for i in range(len(course)):
course_total_score = 0
for j in range(len(students_name)):
course_total_score += scores[i][j]
pjcj = course_total_score/(len(students_name))
print(f"{course[i]}的平均成绩是:{pjcj}")

大佬的解决办法是

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
"""
录入5个学生3门课程的考试成绩
计算每个学生的平均分和每门课的平均分

Version: 0.1
Author: 骆昊
"""
names = ['关羽', '张飞', '赵云', '马超', '黄忠']
courses = ['语文', '数学', '英语']
# 用生成式创建嵌套的列表保存5个学生3门课程的成绩
scores = [[0] * len(courses) for _ in range(len(names))]
# 录入数据
for i, name in enumerate(names):
print(f'请输入{name}的成绩 ===>')
for j, course in enumerate(courses):
scores[i][j] = float(input(f'{course}: '))
print()
print('-' * 5, '学生平均成绩', '-' * 5)
# 计算每个人的平均成绩
for index, name in enumerate(names):
avg_score = sum(scores[index]) / len(courses)
print(f'{name}的平均成绩为: {avg_score:.1f}分')
print()
print('-' * 5, '课程平均成绩', '-' * 5)
# 计算每门课的平均成绩
for index, course in enumerate(courses):
# 用生成式从scores中取出指定的列创建新列表
curr_course_scores = [score[index] for score in scores]
avg_score = sum(curr_course_scores) / len(names)
print(f'{course}的平均成绩为:{avg_score:.1f}分')

案例2:设计一个函数返回指定日期是这一年的第几天。

说明:这个案例源于著名的The C Programming Language上的例子。

我写的办法是

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
"""
设计一个函数返回指定日期是这一年的第几天。
"""
day_dic = {
'1':31,
'2':29,
'3':31,
'4':30,
'5':31,
'6':30,
'7':31,
'8':31,
'9':30,
'10':31,
'11':30,
'12':31,
}
# 获取数据


def a_function():
year = int(input('请输入您想确认的年份:'))
month = int(input('请输入您想确认的日期的月份:'))
day = int(input(f'请输入您想确认的{month}月的几号:'))
#判断闰年
if year/4 != 0 and year/400!=0:
day_dic['2'] = 28
#计算数据
which_day = 0
for x in range(1,month):
which_day += int(day_dic[str(x)])
which_day += day
print(f'{year}{month}{day}号是一年当中的第{which_day}天')

while True:
a_function()

大佬写的办法是

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
def is_leap_year(year):
"""判断指定的年份是不是闰年,平年返回False,闰年返回True"""
return year % 4 == 0 and year % 100 != 0 or year % 400 == 0


def which_day(year, month, date):
"""计算传入的日期是这一年的第几天
:param year: 年
:param month: 月
:param date: 日
"""
# 用嵌套的列表保存平年和闰年每个月的天数
days_of_month = [
[31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31],
[31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
]
# 布尔值False和True可以转换成整数0和1,因此
# 平年会选中嵌套列表中的第一个列表(2月是28天)
# 闰年会选中嵌套列表中的第二个列表(2月是29天)
days = days_of_month[is_leap_year(year)]
total = 0
for index in range(month - 1):
total += days[index]
return total + date


print(which_day(1980, 11, 28)) # 333
print(which_day(1981, 12, 31)) # 365
print(which_day(2018, 1, 1)) # 1
print(which_day(2016, 3, 1)) # 61

案例3:实现双色球随机选号。

说明:双色球属乐透型彩票范畴,由中国福利彩票发行管理中心统一组织发行,在全国范围内销售。红球号码范围为01~33,蓝球号码范围为01~16。双色球每期从33个红球中开出6个号码,从16个蓝球中开出1个号码作为中奖号码,双色球玩法即是竞猜开奖号码的6个红球号码和1个蓝球号码。

我的写法是

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
"""
实现双色球随机选号。
红球号码范围为01~33,蓝球号码范围为01~16。
双色球每期从33个红球中开出6个号码,从16个蓝球中开出1个号码作为中奖号码,双色球玩法即是竞猜开奖号码的6个红球号码和1个蓝球号码。
"""
import random

red_boll = [x for x in range(1,34)]
blue_boll = [x for x in range(1,17)]
# 开红球
red_choice = []
for x in range(6):
a = random.randint(1,len(red_boll))
choice_boll = red_boll[a]

red_choice.append(choice_boll)
red_boll.remove(choice_boll)
# print(red_choice)

#测试
# a = random.randint(1,len(red_boll))
# print(a)
# red_choice.append(a)
# red_boll.remove(a)
# print(red_boll)
# print(red_choice)

#开蓝球
blue_choice= random.randint(1,len(blue_boll))

print('机选的结果是:')
for x in red_choice:
print(x,end=' ')
print('| ' + str(blue_choice))

大佬的写法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
"""
双色球随机选号

Version: 0.1
Author: 骆昊
"""
from random import randint, sample


def display(balls):
"""输出列表中的双色球号码"""
for index, ball in enumerate(balls):
if index == len(balls) - 1:
print('|', end=' ')
print(f'{ball:0>2d}', end=' ')
print()


def random_select():
"""随机选择一组号码"""
# 用生成式生成1到33号的红色球
red_balls = [x for x in range(1, 34)]
# 通过无放回随机抽样的方式选中6个红色球
selected_balls = sample(red_balls, 6)
# 对红色球进行排序
selected_balls.sort()
# 用1到16的随机数表示选中的蓝色球并追加到列表中
selected_balls.append(randint(1, 16))
return selected_balls


n = int(input('机选几注: '))
for _ in range(n):
display(random_select())

集合SET

大佬的集合解释很详细。

50课基础里边