白白的python之路--Day5

5一、使用列表

list:列表也是一种结构化的、非标量类型,它是值的有序序列,每个值都可以通过索引进行标识,定义列表可以将列表的元素放在[]中,多个元素用,进行分隔,可以使用for循环对列表元素进行遍历,也可以使用[][:]运算符取出列表中的一个或多个元素。

下面用代码来解释一些列表的用法:

list1 = [1,3,5,7,100]
print(list)
#乘号表示列表元素的重复
list2 = ['hello']*3
print(list2)
#计算列表长度(元素个数)
print(len(list1))
#下标(索引)运算 ,注意python中是从0开始计算的
print(list1[0]) #1
print(list1[4]) #100
print(list1[-1]) #100
print(list1[-3]) #5
list1[2] #300
print(list1)
#通过循环用下标遍历列表元素
for Index in range(len(list1)):
    print(list1[index])
#通过for循环遍历列表元素
for elem in list1:
    print(elem)
#通过enumerate函数处理列表后再遍历可以同时获得元素索引和值
for Index, elem in enumerate(list1):
    print(Index,elem)

下面的代码演示如何向列表中添加元素和移除元素:

#添加和删除列表中的元素
list1=[1,3,5,7,100]
list1.append(200) #在列表最后添加数字200
list1.insert(2,500) #在列表第三个位置插入数字500
list1+=([1000,1100])
print(list1)
print(len(list1)) #9
#先通过成员运算判断元素是否在列表中,如果存在就删除该元素
if 3 in list1:
    list1.remove(3)
if 1234 in list1:
    list1.remove(1234)
print(list1)
#从指定的位置删除元素
list1.pop(0)
list1.pop(len(list1)-1)
#清空列表元素
list1.clear()
print(list1)

和字符串一样,列表也可以做切片操作,通过切片操作我们可以实现对列表的复制或者将列表中的一部分取出来创建出新的列表,代码如下所示。

poem=['nalan','baijuyi','liqingzhao','libai']
poem+=['wangbo','dufu']
print(poem)
#列表切片
poem2=poem[1:4]
print(poem2)
#也可以通过完整切片操作来复制列表
poem3=poem
poem4=poem[-3,-2]
#还可以通过反向切片操作来获得倒转后的列表的拷贝
poem5=poem[::-1]
print(poem5)

下面的代码实现了对列表的排序操作。

list1 = ['orange', 'apple', 'zoo', 'internationalization', 'blueberry']
list2 = sorted(list1)
# sorted函数返回列表排序后的拷贝不会修改传入的列表
# 函数的设计就应该像sorted函数一样尽可能不产生副作用
list3 = sorted(list1, reverse=True)
# 通过key关键字参数指定根据字符串长度进行排序而不是默认的字母表顺序
list4 = sorted(list1, key=len)
print(list1)
print(list2)
print(list3)
print(list4)
# 给列表对象发出排序消息直接在列表对象上进行排序
list1.sort(reverse=True)
print(list1)

二、生成式和生成器

利用列表的生成式语法来创建列表,代码如下:

f=[x for x in range(1,10)]
print(f) #[1, 2, 3, 4, 5, 6, 7, 8, 9]
f=[x+y for x in 'ASDFF' for y in '1247578']
print(f) #['A1', 'A2', 'A4', 'A7', 'A5', 'A7', 'A8', 'S1', 'S2', 'S4', 'S7', 'S5', 'S7', 'S8', 'D1', 'D2', 'D4', 'D7', 'D5', 'D7', 'D8', 'F1', 'F2', 'F4', 'F7', 'F5', 'F7', 'F8', 'F1', 'F2', 'F4', 'F7', 'F5', 'F7', 'F8']
# 用列表的生成表达式语法创建列表容器
# 用这种语法创建列表之后元素已经准备就绪所以需要耗费较多的内存空间
f=[x**2 for x in range(1,1000)]
print(len(f))
print(sys.getsizeof(f)) #查看对象占用内存的字节数
print(f)
# 请注意下面的代码创建的不是一个列表而是一个生成器对象
# 通过生成器可以获取到数据但它不占用额外的空间存储数据
# 每次需要数据的时候就通过内部的运算得到数据(需要花费额外的时间)
f=(x**2 for x in range(1,1000)) #这里用的是圆括号创建生成器对象
print(sys.getsizeof(f))  # 相比生成式生成器不占用存储数据的空间
print(f)
for val in f:
    print(val)

除了上面提到的生成器语法,Python中还有另外一种定义生成器的方式,就是通过yield关键字将一个普通函数改造成生成器函数。下面的代码演示了如何实现一个生成斐波那契数列的生成器。

def fib(n):
    a, b = 0, 1
    for _ in range(n):
        a, b = b, a + b
        yield a

def main():
    for val in fib(20):
        print(val)

if __name__ == '__main__':
    main()

 三、什么是切片?

参考链接:​​​​​​Python中切片的详细介绍-Python教程-PHP中文网

 四、使用元组

元组也是一种容器数据类型,可以用一个变量(对象)来存储多个数据,不同之处在与元组的元素不能修改。将多个元素组合到一起就成了一个元组,它和列表一样可以保存多条数据。

#定义元组
t=('知白',22,True,'四川成都')
print(t)
#获取元组中的元素
print(t[0])
print(t[3])
#遍历元组中的值
for i in range(len(t)):
    print(t[i])
for member in t:
    print(member)
#重新给元组赋值
# t[0] = '守黑'  # TypeError
# 变量t重新引用了新的元组原来的元组将被垃圾回收
t = ('守黑', 20, True, '河南周口')
print(t)
#将元组转化为列表
person=list(t)
print(person)
#列表是可以修改它的元素的
person[0]='纳兰容若'
person[1]='300'
print(person)
#将列表转化为元组
fruits_list = ['apple', 'banana', 'orange']
fruits_tuple = tuple(fruits_list)
print(fruits_tuple)

为什么有列表了,还需要元组呢?

  1. 元组中的元素是无法修改的,事实上我们在项目中尤其是多线程环境(后面会讲到)中可能更喜欢使用的是那些不变对象(一方面因为对象状态不能修改,所以可以避免由此引起的不必要的程序错误,简单的说就是一个不变的对象要比可变的对象更加容易维护;另一方面因为没有任何一个线程能够修改不变对象的内部状态,一个不变对象自动就是线程安全的,这样就可以省掉处理同步化的开销。一个不变对象可以方便的被共享访问)。所以结论就是:如果不需要对元素进行添加、删除、修改的时候,可以考虑使用元组,当然如果一个方法要返回多个值,使用元组也是不错的选择。
  2. 元组在创建时间和占用的空间上面都优于列表。我们可以使用sys模块的getsizeof函数来检查存储同样的元素的元组和列表各自占用了多少内存空间,这个很容易做到。我们也可以在ipython中使用魔法指令%timeit来分析创建同样内容的元组和列表所花费的时间。

五、使用集合 

Python中的集合跟数学上的集合是一致的,不允许有重复元素,而且可以进行交集、并集、差集等运算。

(1)可以按照下面代码所示的方式来创建和使用集合。

#创建集合的字面量语法
set1={1,2,3,4,3,4,5}
print(set1) #{1, 2, 3, 4, 5}
print('length=%d' % len(set1))
#创建几个的构造器语法(面向对象部分会进行详细讲解)
set2=set(range(1,10))
set3=set((1,2,3,4,6,7,7))
print(set2,set3)
# 创建集合的推导式语法(推导式也可以用于推导集合)
set4={num for num in range(1,100) if num %3==0 or num %5==0}
print(set4)

(2)对集合添加和删除元素

set1.add(6) #在尾部加数字6
print(set1)
set2.update([11,12]) #在尾部加数字11,12
print(set2)
if 4 in set2:
    set2.remove(4)
print(set3.pop())#从指定的位置删除元素
print(set3)

(3)集合的成员、交集、并集、差集等运算

set5={1,9,2,0,7,6}
set6={2,3,4,5,6,7}
print(set5&set6)#求交集
print(set5|set6)#求并集
print(set5-set6)#求差集
print(set5 <= set6)#求子集和超集
print(set5 >= set6)

白白的python之路--Day5

 六、使用字典

字典是另一种可变容器模型,Python中的字典跟我们生活中使用的字典是一样一样的,它可以存储任意类型对象,与列表、集合不同的是,字典的每个元素都是由一个键和一个值组成的“键值对”,键和值通过冒号分开。下面的代码演示了如何定义和使用字典。

#创建字典的字面量语法
scores={'道可道':98,'非常道':90,'名可名':89}
print(scores)
#创建字典的构造器语法
items1=dict(one=1,two=2,three=3)
#通过zip函数将两个序列压成字典
items2=dict(zip(['a','b','c'],'123'))
print(items2)
#创建字典的推导式语法
items3={num:num**2 for num in range(1,10)}
print(items1,items2,items3)
#对字典中所有值进行遍历
for key in scores:
    print(f'{key}:{scores[key]}')
#更新字典中的元素
scores['道可道']=89
scores['名可名']=27
scores['非常道']=20
print(scores)
scores.update(冷面=67, 方启鹤=85)
if '武则天' in scores:
    print(scores['武则天'])
print(scores.get('武则天'))
# get方法也是通过键获取对应的值但是可以设置默认值
print(scores.get('武则天', 60))
# 删除字典中的元素
print(scores.popitem())
print(scores.popitem())
print(scores.pop('骆昊', 100))
# 清空字典
scores.clear()
print(scores)

练习: 

1、在屏幕上显示跑马灯文字

import os
import time

def main():
    content='西风多少恨,吹不散眉弯'
    while True:
        #清理屏幕上的输出
        os.system('cls')
        print(content)
        #休眠200毫秒
        time.sleep(0.2)
        content=content[1:]+content[0]
if __name__=='__main__':
    main()

2、设计一个函数产生指定长度的验证码,验证码由大小写字母和数字构成

import random

def generate_code(code_len=4):
    """
        生成指定长度的验证码

        :param code_len: 验证码的长度(默认4个字符)

        :return: 由大小写英文字母和数字构成的随机验证码
        """
    all_chars='0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
    last_pos=len(all_chars)-1
    code=''
    for _ in range(code_len):
        index=random.randint(0,last_pos)
        code+=all_chars[index]
    return code

这是一个函数,需要后期调用的!所以运行不出来具体的东西。

3、设计一个函数返回给定文件的后缀名

def get_suffix(filename, has_dot=False):
    """
    获取文件名的后缀名

    :param filename: 文件名
    :param has_dot: 返回的后缀名是否需要带点
    :return: 文件的后缀名
    """
    pos = filename.rfind('.')
    if 0 < pos < len(filename) - 1:
        index = pos if has_dot else pos + 1
        return filename[index:]
    else:
        return ''

上一篇:Python “多类型 多环节”场景下 漏斗分析的方式


下一篇:数组测试题