商业数据分析从入门到入职(6)Python程序结构和函数

各位看官朋友,最近“GEEK+”原创·博主大赛TOP 50榜单投票,各位有票的捧个票场,没票的捧个人场,点击https://tp.wjx.top/jq/91687657.aspx,投给第3个cutercorley,如下:
投票
投出您最宝贵的一票,您的支持与鼓励是我继续创作、不断努力的动力,我将继续为大家贡献原创文章、为您排忧解难。

一、Python程序结构

Python中,有3种常见的程序结构:

  • Sequence顺序
    从上向下依次执行。
  • Condition条件
    满足某个条件则执行。
  • Loop循环
    重复执行某个动作。

1.if条件

判断某个变量是否满足某个条件时如下:

possibility_to_rain = 0.7
print(possibility_to_rain > 0.8)
print(possibility_to_rain > 0.3)
possibility_to_rain = 1
print(possibility_to_rain > 0.8)
print(possibility_to_rain > 0.3)

输出:

False
True
True
True

如需本节同步ipynb文件,可以直接点击加QQ群 Python极客部落963624318 在群文件夹商业数据分析从入门到入职中下载即可。

但是如果想在变量满足某个条件时需要执行某个动作,则需要if条件判断语句,如下:

possibility_to_rain = 0.7

if possibility_to_rain > 0.8:
    print("Do take your umberalla with you.") ## 这个地方标准格式是四个空格的缩进
elif possibility_to_rain > 0.3:
    print("Take your umberalla just in case. hahaha")    
else:
    print("Enjoy the sunshine!")
print('hello')

输出:

Take your umberalla just in case. hahaha

这段代码的意思是:
如果possibility_to_rain > 0.8为True,则执行print("Do take your umberalla with you."),如果不满足前述条件,但满足possibility_to_rain > 0.3,则执行print("Take your umberalla just in case. hahaha"),否则执行print("Enjoy the sunshine!")
if语句执行完后,再执行后面的语句,如print('hello')
需要注意缩进,if、elif、else语句后面的语句都应该缩进4格并保持对齐,即通过缩进控制代码块和代码结构,而不像其他语言使用{}来控制代码结构,如下:
python code blocks

前面也看到,出现了很多以#开头的代码和文字性说明,代码颜色也是和其他代码有所区别的,这就是Python中的单行注释,注释后的代码不会被执行,而只能起到说明作用,这段代码中这个地方标准格式是四个空格的缩进#注释,这一行前面的代码能正常执行,#后的文字不会执行、也不会报错、作为解释性语句。

扫描二维码关注公众号,回复: 11816445 查看本文章

除了对数值进行判断,还能对字符串进行判断:

card_type = "debit"
account_type = "checking"

if card_type == "debit":
    if account_type == "checking":
        print("Checkings selectd.")
    else:
        print("Savings selected.")
else:
    print("Credit card.")

输出:

Take your umberalla just in case. hahaha
hello

可以看到,使用到了条件判断的嵌套

2.循环

while循环

之前要是需要执行重复操作,可能如下:

count =1
print(count)
count+=1
print(count)
count+=1
print(count)
count+=1
print(count)
count+=1
print(count)
count+=1
print(count)
count+=1
print(count)
count+=1
print(count)
count+=1
print(count)
count+=1
print(count)

输出:

1
2
3
4
5
6
7
8
9
10

显然,代码很冗长,此时就可以使用循环进行优化。

使用while循环如下:

count = 1
while count <= 10:
    print(count)
    count += 1

执行效果与前面相同;
需要注意,循环一般要有停止的条件,当满足count <= 10时循环会一直执行,直到count = 11时就会不符合、从而退出循环;
如果没有停止条件,则可能陷入死循环、消耗内存。

再如:

cnt = 1
while True:
    print("cnt = %d" % cnt)
    ch = input('Do you want to continue? [y:n]: ')
    if ch == 'y':
        cnt += 1
    else:
        break        

输出如下:
python while loop break

可以看到,虽然循环条件为True,是恒成立的,但是循环内部进行了条件判断,输入的是y就会一直循环,输入其他则执行break退出循环;
但是需要注意,这里只有严格地输入y才能继续循环,但是输入yes都会退出循环,所以要想进一步控制运行逻辑、还需要对代码进行完善。

在Python中,else也可以与while循环结合使用,如果循环不是因调用break而结束的,将执行else中的语句,这可以用于判断循环是不是完全执行,例如前面第1个循环的例子是不是运行了10次。

如下:

count = 1
while count < 11:
    print(count)
    count = count + 1
else:
    print('Counting complete.')

    print()
count = 1
while count < 11:
    print(count)
    count = count + 1
    if count == 8:
        break
else:
    print('Counting complete.')

输出:

1
2
3
4
5
6
7
8
9
10
Counting complete.

1
2
3
4
5
6
7

可以看到:
第一个循环并没有因为break而停止循环,因此在执行完循环语句后执行了else语句;
第二个循环因为count为8时满足if条件而退出循环、并未将循环执行完毕,因此未执行else语句。

再如:

count=0
while count < 11:
    print("while count:",count)
    count = count + 1
    if count == 11:
        break
else:
    print("else:",count)

输出:

while count: 0
while count: 1
while count: 2
while count: 3
while count: 4
while count: 5
while count: 6
while count: 7
while count: 8
while count: 9
while count: 10

显然,此时因为执行最后一次循环时满足if条件而执行了break语句,因此并未执行else语句块。

for循环

经常与for循环同时出现的还有rangerange(self, /, *args, **kwargs)函数有以下两种常见的用法:

range(stop) -> range object
range(start, stop[, step]) -> range object

该函数返回一个对象,该对象以step为步长生成从start(包含)到stop(排除)的整数序列。例如range(i, j)产生i,i+1,i+2,…,j-1的序列。

输入:

for i in range(10):
    print(i)

输出:

0
1
2
3
4
5
6
7
8
9

再如:

for i in range(4,10):
    print(i)
    
print()
for i in range(4,10,2):
    print(i)
    
print()
for i in range(5):
    print('Corley')
    
print()
for i in range(5):
    print('Corley'[i])

输出:

4
5
6
7
8
9

4
6
8

Corley
Corley
Corley
Corley
Corley

C
o
r
l
e

可以看到,for循环内也可以执行与i无关的操作;
还可以用来遍历字符串。

for循环中也可以使用break语句来终止循环,如下:

for i in range(10):
    print(i) 
    if i == 5:
        break

输出:

0
1
2
3
4
5

再如:

result = 0

for num in range(1,100):
    if num % 2 == 0:
        result = result + num
        
print(result)

输出:

2450

上面的例子实现了计算从1到100(不包括)的所有偶数的和。

3.案例-王者荣耀纯文本分析

目标是从以下文本提取出所有的英雄信息链接、头像图片链接、英雄名称,如herodetail/194.shtml、http://game.gtimg.cn/images/yxzj/img201606/heroimg/194/194.jpg和苏烈:

<ul class="herolist clearfix"><li><a href="herodetail/194.shtml" target="_blank"><img src="http://game.gtimg.cn/images/yxzj/img201606/heroimg/194/194.jpg" width="91px" alt="苏烈">苏烈</a></li><li><a href="herodetail/195.shtml" target="_blank"><img src="http://game.gtimg.cn/images/yxzj/img201606/heroimg/195/195.jpg" width="91px" alt="百里玄策">百里玄策</a></li><li><a href="herodetail/196.shtml" target="_blank"><img src="http://game.gtimg.cn/images/yxzj/img201606/heroimg/196/196.jpg" width="91px" alt="百里守约">百里守约</a></li><li><a href="herodetail/193.shtml" target="_blank"><img src="http://game.gtimg.cn/images/yxzj/img201606/heroimg/193/193.jpg" width="91px" alt=""></a></li></ul>

我们可以先找出一个英雄的信息,即使用下标进行字符串切分,找下标时使用find()方法。
例如,对于链接http://game.gtimg.cn/images/yxzj/img201606/heroimg/194/194.jpg,如果找到第一个h字母和最后一个g字母的下标,就可以通过切分将该链接提取出来。

先读入字符串,如下:

page_hero = '''<ul class="herolist clearfix"><li><a href="herodetail/194.shtml" target="_blank"><img src="http://game.gtimg.cn/images/yxzj/img201606/heroimg/194/194.jpg" width="91px" alt="苏烈">苏烈</a></li><li><a href="herodetail/195.shtml" target="_blank"><img src="http://game.gtimg.cn/images/yxzj/img201606/heroimg/195/195.jpg" width="91px" alt="百里玄策">百里玄策</a></li><li><a href="herodetail/196.shtml" target="_blank"><img src="http://game.gtimg.cn/images/yxzj/img201606/heroimg/196/196.jpg" width="91px" alt="百里守约">百里守约</a></li><li><a href="herodetail/193.shtml" target="_blank"><img src="http://game.gtimg.cn/images/yxzj/img201606/heroimg/193/193.jpg" width="91px" alt="铠">铠</a></li></ul>
'''

此时再通过一步步地获取与目标相关字符的下标和根据下标切片来获取目标字符串,如获取图片链接如下:

start_link = page_hero.find('<img src="')
print(start_link)
start_quote = page_hero.find('"', start_link)
end_quote = page_hero.find('"', start_quote+1)
hero_link = page_hero[start_quote+1:end_quote]
print(hero_link)

输出:

81
http://game.gtimg.cn/images/yxzj/img201606/heroimg/194/194.jpg

此时再依次获取英雄名和信息链接如下:

# 第1个英雄
start_link = page_hero.find('<a href="')
start_quote = page_hero.find('"', start_link)
end_quote = page_hero.find('"', start_quote+1)
hero_info1 = page_hero[start_quote+1:end_quote]
print(hero_info1)
start_link = page_hero.find('<img src="', end_quote+1)
start_quote = page_hero.find('"', start_link)
end_quote = page_hero.find('"', start_quote+1)
hero_link1 = page_hero[start_quote+1:end_quote]
print(hero_link1)
end_bracket = page_hero.find('>', end_quote+1)
start_bracket = page_hero.find('<', end_bracket+1)
hero_name1 = page_hero[end_bracket+1:start_bracket]
print(hero_name1)

输出:

herodetail/194.shtml
http://game.gtimg.cn/images/yxzj/img201606/heroimg/194/194.jpg
苏烈

显然,已经获取到第1个英雄的完整信息。

此时再获取第2个英雄的信息,如下:

# 第2个英雄
page_hero = page_hero[start_bracket:]
start_link = page_hero.find('<a href="')
start_quote = page_hero.find('"', start_link)
end_quote = page_hero.find('"', start_quote+1)
hero_info2 = page_hero[start_quote+1:end_quote]
print(hero_info2)
start_link = page_hero.find('<img src="', end_quote+1)
start_quote = page_hero.find('"', start_link)
end_quote = page_hero.find('"', start_quote+1)
hero_link2 = page_hero[start_quote+1:end_quote]
print(hero_link2)
end_bracket = page_hero.find('>', end_quote+1)
start_bracket = page_hero.find('<', end_bracket+1)
hero_name2 = page_hero[end_bracket+1:start_bracket]
print(hero_name2)

输出:

herodetail/195.shtml
http://game.gtimg.cn/images/yxzj/img201606/heroimg/195/195.jpg
百里玄策

需要注意:
第二次切分不需要再在原字符串上进行切分、而只要从上次切分的位置开始查找和切分即可,所以page_hero = page_hero[end_quote:]即是将上次切分之后的子字符串重新赋值给page_hero作为新字符串;
因为各个英雄信息的字符串形式是一样的,所以可以直接利用查找第一个英雄的方式即可。

查找第3个和第4个英雄也类似如下:

# 第3个英雄
page_hero = page_hero[start_bracket:]
start_link = page_hero.find('<a href="')
start_quote = page_hero.find('"', start_link)
end_quote = page_hero.find('"', start_quote+1)
hero_info3 = page_hero[start_quote+1:end_quote]
print(hero_info3)
start_link = page_hero.find('<img src="', end_quote+1)
start_quote = page_hero.find('"', start_link)
end_quote = page_hero.find('"', start_quote+1)
hero_link3 = page_hero[start_quote+1:end_quote]
print(hero_link3)
end_bracket = page_hero.find('>', end_quote+1)
start_bracket = page_hero.find('<', end_bracket+1)
hero_name3 = page_hero[end_bracket+1:start_bracket]
print(hero_name3)

# 第4个英雄
page_hero = page_hero[start_bracket:]
start_link = page_hero.find('<a href="')
start_quote = page_hero.find('"', start_link)
end_quote = page_hero.find('"', start_quote+1)
hero_info4 = page_hero[start_quote+1:end_quote]
print(hero_info4)
start_link = page_hero.find('<img src="', end_quote+1)
start_quote = page_hero.find('"', start_link)
end_quote = page_hero.find('"', start_quote+1)
hero_link4 = page_hero[start_quote+1:end_quote]
print(hero_link4)
end_bracket = page_hero.find('>', end_quote+1)
start_bracket = page_hero.find('<', end_bracket+1)
hero_name4 = page_hero[end_bracket+1:start_bracket]
print(hero_name4)

输出:

herodetail/196.shtml
http://game.gtimg.cn/images/yxzj/img201606/heroimg/196/196.jpg
百里守约
herodetail/193.shtml
http://game.gtimg.cn/images/yxzj/img201606/heroimg/193/193.jpg
铠

可以看到,找4个英雄的思路都大致如下:
(1)找到第一个出现的<img src= >=>start_link;
(2)找到第一个出现的"=>start_quote;
(3)找到start_quote+1之后那个引号 end_quote;
(4)end_quote+1找到后面的>记作 end_bracket;
(5)end_bracket+1 找到 start_bracket;
(6)抛弃start_bracket之前的所有内容,再根据上面的方法找。

可以看到,3部分代码也有很大部分相似,因此可以使用循环来简化代码:

# 使用循环简化代码
page_hero = '''<ul class="herolist clearfix"><li><a href="herodetail/194.shtml" target="_blank"><img src="http://game.gtimg.cn/images/yxzj/img201606/heroimg/194/194.jpg" width="91px" alt="苏烈">苏烈</a></li><li><a href="herodetail/195.shtml" target="_blank"><img src="http://game.gtimg.cn/images/yxzj/img201606/heroimg/195/195.jpg" width="91px" alt="百里玄策">百里玄策</a></li><li><a href="herodetail/196.shtml" target="_blank"><img src="http://game.gtimg.cn/images/yxzj/img201606/heroimg/196/196.jpg" width="91px" alt="百里守约">百里守约</a></li><li><a href="herodetail/193.shtml" target="_blank"><img src="http://game.gtimg.cn/images/yxzj/img201606/heroimg/193/193.jpg" width="91px" alt="铠">铠</a></li></ul>
'''
for i in range(4):
    print('第%d个英雄:' % (i+1))
    start_link = page_hero.find('<a href="')
    start_quote = page_hero.find('"', start_link)
    end_quote = page_hero.find('"', start_quote+1)
    hero_info = page_hero[start_quote+1:end_quote]
    print(hero_info)
    start_link = page_hero.find('<img src="', end_quote+1)
    start_quote = page_hero.find('"', start_link)
    end_quote = page_hero.find('"', start_quote+1)
    hero_link = page_hero[start_quote+1:end_quote]
    print(hero_link)
    end_bracket = page_hero.find('>', end_quote+1)
    start_bracket = page_hero.find('<', end_bracket+1)
    hero_name = page_hero[end_bracket+1:start_bracket]
    print(hero_name)
    page_hero = page_hero[start_bracket:]

输出:

1个英雄:
herodetail/194.shtml
http://game.gtimg.cn/images/yxzj/img201606/heroimg/194/194.jpg
苏烈
第2个英雄:
herodetail/195.shtml
http://game.gtimg.cn/images/yxzj/img201606/heroimg/195/195.jpg
百里玄策
第3个英雄:
herodetail/196.shtml
http://game.gtimg.cn/images/yxzj/img201606/heroimg/196/196.jpg
百里守约
第4个英雄:
herodetail/193.shtml
http://game.gtimg.cn/images/yxzj/img201606/heroimg/193/193.jpg
铠

显然,代码精简很多。

二、函数的介绍和基本使用

函数是一段命名的代码,并且独立于所有其他代码。
函数可以接受任何类型的输入参数,并返回任意数量和类型的输出结果。
简而言之,函数可以代替大段代码,在需要使用这些代码的时候、直接调用函数即可,而不再需要重复大段代码,很大程度上优化了代码的结构、提高了代码的可读性

定义一个不做任何事的函数如下:

# An empty function that does nothing
def do_nothing():
    pass

do_nothing()
type(do_nothing)

输出:

function

其中,do_nothing()是调用函数,即函数名()

定义一个不带参数和返回值的函数如下:

# A function without parameters and returns values
def greeting():
    print("Hello Python")

# Call the function
a = greeting()

输出:

Hello Python

以后需要打印Hello Python的地方,就不用再使用print("Hello Python")语句,直接调用greeting()即可。

还可以定义带参数、但是不带返回值的函数:

# A function with a parameter that returns nothing
def greeting(name):
    print("Hello %s" % name)

# Call the function
greeting('Corley')

输出:

Hello Corley

此时在调用函数时,传入了参数'Corley',会在函数内部使用,如果参数值变化,在函数内部被使用的变量也会同步变化,导致结果也可能变化。

但是此时:

print(a)

输出:

None

即返回为空,这是因为在函数内部并未定义返回值。
在需要时可以在函数内部定义返回值,以便用于下一步的运算。

如下:

# A function with a parameter and return a string
def greeting_str(name):
    return "Hello again " + name

# Use the function
s = greeting_str("Corley")
print(s)

输出:

Hello again Corley

像许多编程语言一样,Python支持位置参数,其值按顺序复制到相应的参数中。即可以给函数传递多个参数,如下:

# A function with 3 parameters
def menu(wine, entree, dessert):
    return "wine:{},entree:{},dessert:{}".format(wine,entree,dessert)

# Get a menu
menu('chardonnay', 'chicken', 'cake')

输出:

'wine:chardonnay,entree:chicken,dessert:cake'

为了避免位置参数混淆,可以通过参数对应的名称来指定参数,甚至可以使用与函数中定义不同的顺序来指定参数,即关键字参数。
如下:

menu(entree='beef', dessert='cake', wine='bordeaux')

输出:

'wine:bordeaux,entree:beef,dessert:cake'

显然,此时不按照顺序也可以实现传参。

甚至可以混合使用位置参数和关键字参数;
但是需要注意,在输入任何关键字参数之前,必须提供所有位置参数。

如果函数调用者未提供任何参数的默认值,则可以为参数设置默认值。
如下:

# default dessert is pudding
def menu(wine, entree, dessert='pudding'):
    return "wine:{},entree:{},dessert:{}".format(wine,entree,dessert)


# Call menu without providing dessert
menu('chardonnay', 'chicken')

输出:

'wine:chardonnay,entree:chicken,dessert:pudding'

可以看到,此时也可以不给dessert参数传值也能正常运行,因为在定义函数时已经提供了默认值。

当然,也可以给dessert参数传值,此时就会使用传递的值代替默认值,如下:

# Default value will be overwritten if caller provide a value
menu('chardonnay', 'chicken', 'doughnut')

输出:

'wine:chardonnay,entree:chicken,dessert:doughnut'

在函数中,存在作用域,即变量在函数内外是否有效。
如下:

x = 1
def new_x():
    x = 5
    print(x)
    
    
def old_x():
    print(x)
    
new_x()
old_x()

输出:

5
1

显然,第一个函数中的x在函数内部,属于局部变量,局部变量只能在当前函数内部使用;
第二个函数使用的x函数内部并未定义,因此使用函数外部的x,即全局变量,全局变量可以在函数内部使用,也可以在函数外部使用;
函数内部定义了与全局变量同名的局部变量后,不会改变全局变量的值。

要想在函数内部使用全局变量并进行修改,需要使用global关键字进行声明。
如下:

x = 1

def change_x():
    global x
    print('before changing inside,', x)
    x = 3
    print('after changing inside,', x)
    
print('before changing outside,', x)
change_x()
print('after changing outside,', x)

输出:

before changing outside, 1
before changing inside, 1
after changing inside, 3
after changing outside, 3

可以看到,此时在函数内部对变量进行修改后,函数外部也发生改变。

此时可以对之前王者荣耀纯文本分析案例进一步优化:

# 使用函数实现
def extract_info(current_page):
    start_link = current_page.find('<a href="')
    start_quote = current_page.find('"', start_link)
    end_quote = current_page.find('"', start_quote+1)
    hero_info = current_page[start_quote+1:end_quote]
    print(hero_info)
    start_link = current_page.find('<img src="', end_quote+1)
    start_quote = current_page.find('"', start_link)
    end_quote = current_page.find('"', start_quote+1)
    hero_link = current_page[start_quote+1:end_quote]
    print(hero_link)
    end_bracket = current_page.find('>', end_quote+1)
    start_bracket = current_page.find('<', end_bracket+1)
    hero_name = current_page[end_bracket+1:start_bracket]
    print(hero_name)
    return start_bracket


start_bracket = 0
page_hero = '''<ul class="herolist clearfix"><li><a href="herodetail/194.shtml" target="_blank"><img src="http://game.gtimg.cn/images/yxzj/img201606/heroimg/194/194.jpg" width="91px" alt="苏烈">苏烈</a></li><li><a href="herodetail/195.shtml" target="_blank"><img src="http://game.gtimg.cn/images/yxzj/img201606/heroimg/195/195.jpg" width="91px" alt="百里玄策">百里玄策</a></li><li><a href="herodetail/196.shtml" target="_blank"><img src="http://game.gtimg.cn/images/yxzj/img201606/heroimg/196/196.jpg" width="91px" alt="百里守约">百里守约</a></li><li><a href="herodetail/193.shtml" target="_blank"><img src="http://game.gtimg.cn/images/yxzj/img201606/heroimg/193/193.jpg" width="91px" alt="铠">铠</a></li></ul>
'''
for i in range(4):
    print('第%d个英雄:' % (i+1))
    page_hero = page_hero[start_bracket:]
    start_bracket = extract_info(page_hero)    

输出:

1个英雄:
herodetail/194.shtml
http://game.gtimg.cn/images/yxzj/img201606/heroimg/194/194.jpg
苏烈
第2个英雄:
herodetail/195.shtml
http://game.gtimg.cn/images/yxzj/img201606/heroimg/195/195.jpg
百里玄策
第3个英雄:
herodetail/196.shtml
http://game.gtimg.cn/images/yxzj/img201606/heroimg/196/196.jpg
百里守约
第4个英雄:
herodetail/193.shtml
http://game.gtimg.cn/images/yxzj/img201606/heroimg/193/193.jpg
铠

显然,循环和函数结合使用,实现了功能,并且进一步简化代码。

除了使用for循环,还可以使用while循环,如下:

# 使用函数实现
def extract_info(i, current_page):
    start_link = current_page.find('<a href="')
    start_quote = current_page.find('"', start_link)
    end_quote = current_page.find('"', start_quote+1)
    hero_info = current_page[start_quote+1:end_quote]    
    start_link = current_page.find('<img src="', end_quote+1)
    start_quote = current_page.find('"', start_link)
    end_quote = current_page.find('"', start_quote+1)
    hero_link = current_page[start_quote+1:end_quote]    
    end_bracket = current_page.find('>', end_quote+1)
    start_bracket = current_page.find('<', end_bracket+1)
    hero_name = current_page[end_bracket+1:start_bracket]    
    if hero_info.startswith('hero'):
        print('第%d个英雄:' % i)
        print(hero_info)
        print(hero_link)
        print(hero_name)
        return start_bracket
    else:
        return -1


start_bracket = 0
i = 1
page_hero = '''<ul class="herolist clearfix"><li><a href="herodetail/194.shtml" target="_blank"><img src="http://game.gtimg.cn/images/yxzj/img201606/heroimg/194/194.jpg" width="91px" alt="苏烈">苏烈</a></li><li><a href="herodetail/195.shtml" target="_blank"><img src="http://game.gtimg.cn/images/yxzj/img201606/heroimg/195/195.jpg" width="91px" alt="百里玄策">百里玄策</a></li><li><a href="herodetail/196.shtml" target="_blank"><img src="http://game.gtimg.cn/images/yxzj/img201606/heroimg/196/196.jpg" width="91px" alt="百里守约">百里守约</a></li><li><a href="herodetail/193.shtml" target="_blank"><img src="http://game.gtimg.cn/images/yxzj/img201606/heroimg/193/193.jpg" width="91px" alt="铠">铠</a></li></ul>
'''
while True:    
    page_hero = page_hero[start_bracket:]
    start_bracket = extract_info(i, page_hero)
    i += 1
    if start_bracket == -1:
        break

效果与前面一样。

还有额外的代码结构的练习,如有需要,可以直接点击加QQ群 Python极客部落963624318 在群文件夹商业数据分析从入门到入职中下载即可。

三、列表

之前的数据类型一般都是单个值,而不能再存储像矩阵、数组这种结构存储多个元素,要是需要达到这样的目标、需要使用新的数据类型,Python中提供了4种数据结构来存储多个对象,称它们为容器类型(Container Types),包括如下几种类型:

  • 列表List
  • 元组Tuple
  • 字典Dictionary
  • 集合Set

1.创建列表

其实,字符串其实也是一种序列,是由字符组成的序列。

字符串可以通过切片访问部分元素:

# sequence of characters
s="Corley!"
s[2:4]

输出:

'rl'

字符串是一个字符序列,列表是一个对象的序列。当对象的顺序很重要时就会使用列表。
创建和访问列表如下:

#sequence of anything
p = ['C','o','r','l','e','y','!']
p[2:4]

输出:

['r', 'l']

可以看到,列表是用[]定义的,元素放入其中,用,隔开。

再如:

def how_many_days(month):
    days_in_month=[31,28,31,30,31,30,31,31,30,31,30,31]
    return days_in_month[month-1]

display(how_many_days(2), how_many_days(5), how_many_days(10))

输出:

28

31

31

可以看到,直接获取到了2、5、8月的天数。

还可以直接创建空列表,如下:

empty_list = []
another_empty_list = list()
display(empty_list,another_empty_list)

输出:

[]

[]

可以看到,输出了两个空列表。

还可以从字符串中分割出列表,如下:

weekday_str = 'Monday,Tuesday,Wednesday,Thursday,Friday'
weekdays = weekday_str.split(',')
weekdays

输出:

['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday']

以列表作为元素创建列表如下:

obj_list = ["string", 1, True, 3.14]
list_of_list = [empty_list, weekdays, obj_list]
list_of_list

输出:

[[],
 ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday'],
 ['string', 1, True, 3.14]]

此即列表的嵌套。
再如:

dal_memeber= [['Corley',18],['Jack',18],['Shirely',48],['Tom',18]]
print(dal_memeber)
print(dal_memeber[0])
print(dal_memeber[0][1])

输出:

[['Corley', 18], ['Jack', 18], ['Shirely', 48], ['Tom', 18]]
['Corley', 18]
18

列表可以定位和切片如下:

display(weekdays[0],weekdays[1:3])

输出:

'Monday'

['Tuesday', 'Wednesday']

还可以通过赋值改变列表中的元素,如下:

weekdays[0] = "Sunday"
weekdays

输出:

['Sunday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday']

显然,第一个元素已经改变。

2.删除元素

还可以删除列表中的元素。
一种方式是使用del关键字,基于下标删除,如下:

del weekdays[0]
weekdays

输出:

['Tuesday', 'Wednesday', 'Thursday', 'Friday']

显然,第一个元素被删除。

再如:

al = ['A', 'B', 'C', 'D', 'E', 'F', 'G']
del al[3:]
al

输出:

['A', 'B', 'C']

一次性删除多个元素。

还有一种方式是使用update()方法,基于元素删除。
如下:

weekdays.remove('Friday')
weekdays

输出:

['Tuesday', 'Wednesday', 'Thursday']

但是如果列表中不存在这个元素时,会报错,如下:

weekdays.remove('Friday')
weekdays

报错:

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-20-b508ecb8e563> in <module>
----> 1 weekdays.remove('Friday')
      2 weekdays

ValueError: list.remove(x): x not in list

因为weekdays中没有元素'Friday',因此会报错。
此时可以先进行判断,如果元素存在于列表中则删除,否则不删除;
判断一个元素是否存在于列表中可以用in关键字,存在则返回True,否则返回False。
如下:

if 'Friday' in weekdays:
    weekdays.remove('Friday')
else:
    print('element not exists')

输出:

element not exists

in的用法再如:

weekdays = ['Monday','Tuesday','Wednesday','Thursday','Friday']
'Friday' in weekdays

输出:

True

还可以判断某个元素是否不在列表中,如下:

'Fri' not in weekdays

输出:

4

5

除了使用delremove()删除元素,也可以使用pop()弹出元素,该方法不仅可以弹出元素,还能返回被弹出的元素,如果未传递参数,则默认弹出并返回最后一个元素,传递了下标参数则弹出并返回相应的元素。
如下:

seasons = ['spring', 'summmer', 'autumn', 'winter']
last_season = seasons.pop()
print("last_season = ", last_season, "\nseasons = ", seasons)

输出:

last_season =  winter 
seasons =  ['spring', 'summmer', 'autumn']

再如:

first_season = seasons.pop(0)
print("first_season = ", first_season, "\nseasons = ", seasons)

输出:

first_season =  spring 
seasons =  ['summmer', 'autumn']

3.添加元素

向列表中添加元素也有多种方式:
一种是使用append()方法,该方法是将元素添加到列表末尾。
如下:

weekdays.append('Friday')
weekdays

输出:

['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Friday']

可以看到,列表中允许出现重复元素。

一种是insert()方法,可以指定位置添加元素。
如下:

weekdays.insert(0, 'Monday')
weekdays

输出:

['Monday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Friday']

两个列表也可以直接相加、形成新的列表。
如下:

weekend = ['Saturday', 'Sunday']
weekdays = weekdays + weekend
weekdays

输出:

['Monday',
 'Monday',
 'Tuesday',
 'Wednesday',
 'Thursday',
 'Friday',
 'Friday',
 'Saturday',
 'Sunday']

还可以根据元素获取其再在列表中的下标位置:

display(weekdays.index('Thursday'),weekdays.index('Friday'))

输出:

4

5

可以看到,有重复元素时,会返回第一个下标。

猜你喜欢

转载自blog.csdn.net/CUFEECR/article/details/108751537
今日推荐