04 -Python入门- Lesson4 控制流

04 Python入门 Lesson4 控制流

文章目录

  • 04 Python入门 Lesson4 控制流
    • 2.条件语句(1-7小节)
      • 按位与或,逻辑与或的区别(选学)
    • 8.For循环
    • 17.Zip 和 Enumerate(选学)
    • 20.列表推导式

对于任何一种编程语言,控制流(循环)都是非常重要的。if条件语句、for……in循环、while循环是python控制流的核心,本节请认真学习。如果想加深理解,也可以再参考 扩展链接

2.条件语句(1-7小节)

条件对应的是1-7小节,就是当if后面的描述成立的时候,程序要做blabla,这里课程中讲解和练习都挺丰富,请认真完成练习。

按位与或,逻辑与或的区别(选学)

在Python中的与或分为按位与逻辑两种。

  • 按位:严格比较前后的两个元素。
    • 按位与&
    • 按位或|
  • 逻辑:对前后的可迭代的结构(比如列表)进行比较。
    • 逻辑与and
    • 逻辑或or
  • 逻辑的方式适用更广,在逻辑和位都可使用时,结果一致。

看以下两个例子便于理解(#后面是结果):

## 对于布尔数
a = True
b = False
print (a & b)  # 输出False
print (a | b)  # 输出True
print (a and b)  # 输出False
print (a or b)  # 输出True

## 对于列表
a_list = [True, False, True]
b_list = [True, True, False]
print (a_list & b_list)  # error
print (a_list | b_list)  # error
print (a_list and b_list)  # 输出[True, True, False]
print (a_list or b_list)  # 输出[True, False, True]

而到了ndarray这种数据结构(numpy的结构),& 和 | 也是可以运用的(可以直接作用在ndarray上面,不会报错)。而numpy中特意提供了.logical_and, logical_or, logical_not的逻辑与或非方法。那么既然按位的 & 和 | 可以处理了,为什么ndarray还要提供logical的这3个方法呢?因为性能会更好一点,我们可以认为ndaary提供的方法做了优化(极小规模测试了下,大概有10%的改善),代码和说明如下:

# 定义2维的ndarray(注意,经测试如果用True和False没有改善)
a3 = np.array([
    [1, 0, 1, 1, 1, 1, 0, 1],
    [1, 1, 0, 0, 1, 1, 0, 0],
    [0, 1, 0, 1, 0, 0, 1, 1],
    [1, 1, 1, 0, 1, 1, 0, 1],
    [1, 0, 1, 1, 1, 1, 1, 0],
    [0, 1, 0, 1, 0, 1, 0, 1],
    [1, 0, 1, 1, 1, 1, 1, 0],
    [0, 0, 0, 1, 0, 0, 1, 1]])
b3 = np.array([
    [0, 0, 0, 1, 0, 0, 0, 1],
    [0, 1, 0, 1, 0, 0, 1, 1],
    [1, 1, 1, 0, 1, 1, 0, 1],
    [1, 0, 1, 1, 1, 1, 1, 0],
    [0, 1, 0, 1, 0, 1, 0, 1],
    [1, 0, 1, 1, 1, 1, 1, 0],
    [1, 1, 0, 0, 1, 0, 0, 0],
    [1, 1, 1, 0, 1, 0, 1, 1]])
    
# 定义两种方式的比较函数
def compare1s():
    return a3 & b3, a3 | b3

def compare1bs():
    return np.logical_and(a3, b3), np.logical_or(a3, b3)

# 使用timeit是重复的,因为cpu有占用,所以用repeat进行多次,取最小的
# 如果不用repeat可以直接使用timeit如下:
# t = timeit('compare1b()', 'from __main__ import compare1b', number=100000)
# timeit的中文参考:https://www.cnblogs.com/PrettyTom/p/6657984.html
# timeit官方文档:https://docs.python.org/3/library/timeit.html
t3 = min(repeat('compare1s()', 'from __main__ import compare1s', number=100000, repeat=10))
t4 = min(repeat('compare1bs()', 'from __main__ import compare1bs', number=100000, repeat=10))

print(t3, t4, t4 / t3)    
# logical_and官方文档:https://docs.scipy.org/doc/numpy-1.13.0/reference/generated/numpy.logical_and.html

### result:
### 0.3266788399996585 0.284688735002419 0.8714636521995627

从结果看出,logical_and的方式时间缩短到了87%。

8.For循环

Python的循环有两种,for循环和while循环。抓狂了?为什么有两种循环呢!!!

**for循环:**从名字上看for是遍历,常见的是结合in的判断:

for i in list:
    pass

这个意思就是说,当i在list中的时候,blabla。那么既然是遍历,这个i就是从list里面第一个到最后一个,都run一遍,之后结束。所以for in的对象是一个可迭代的对象(不要晕看例子):

#先看一个列表的例子
list = ['I ', 'love ', 'python ', 666, '!']
for i in list:
    print(i, end = '')
    #end = ''的意思是结尾不换行    
#---输出如下---
I love python 666!
  
#再看一下字符串的例子
string = 'GOOD'
for i in string:
    print(i)
#---输出如下---    
G
O
O
D
  
#看到这里,大家就明白了列表和字符串都是可迭代对象,因为能够按照顺序从同到尾遍历一下。

**while循环:**那么while呢,就是当…时候,做…的意思。和for不同,只要while这行判断成立,就会一直做下去。

综上所述,for in 适合可迭代目标的循环,while适合不知道要循环多少次,每次需要判断状态的循环。两个的区别咱们来个对比做小结:

  1. for loops:
    1. know number of iterations
    2. can end early via break
    3. uses a counter
    4. can rewrite using a while loop
  2. while loops:
    1. unbounded number of iterations
    2. can end early via break
    3. can use a counter but must initialize before loop and increment it inside loop
    4. may not be able to rewrite using a for loop
  3. 咱们来个计算阶乘的例子,两个循环代码如下:
#for loop solution
n = 5
fact = 1
for i in range(2, n + 1):
    fact = fact * i
print(str(n) + ' factorial is ' + str(fact))
  
#while loop solution
n = 5
fact = 1
i = 2
#while要初始化i
while i <= n:
    fact = fact * i
    i = i + 1
    #在循环中要对i进行更新否则会进入死循环
print(str(n) + ' factorial is ' + str(fact))
  
#---输出是一样的---
5 factorial is 120

OK,大家看明白了么?for in 这种循环方式对于可迭代目标更加简洁(也能用enumerate再简化一点点,有兴趣的可以自行搜索)。但是其实两种都是OK的,是个人风格问题。

17.Zip 和 Enumerate(选学)

我们先来说zip,就是拉链的意思,可以把进行组合和拆分,方便进行数据的处理。课程里的例子非常详细。其实zip函数可以进行行列转换,感兴趣的话:参考链接

Enumerate函数,其实就是简化for的一个内置函数,让你的循环更漂亮!

20.列表推导式

列表推导式(List Comprehension):可以把一个设定初始空值,用条件循环填充的循环,简化成一个赋值语句,对比以下,注意else语句的位置是在前面:

#for loop:
capitalized_cities = []
for city in cities:
    capitalized_cities.append(city.title())
    
#list comprehension:
capitalized_cities = [city.title() for city in cities]

#list comprehension else:
squares = [x**2 if x % 2 == 0 else x + 3 for x in range(9)]

书中练习的解释(要先做完在看呦):

#练习1
names = ["Rick Sanchez", "Morty Smith", "Summer Smith", "Jerry Smith", "Beth Smith"]
first_names = [name.split()[0].lower() for name in names]
##此处split会把Rick Sanchez分解为Rick和Sanchez,通过[0]就是选定了Rick
print(first_names)
#['rick', 'morty', 'summer', 'jerry', 'beth']

#练习3
scores = {
             "Rick Sanchez": 70,
             "Morty Smith": 35,
             "Summer Smith": 82,
             "Jerry Smith": 23,
             "Beth Smith": 98
          }

passed = [name for name, score in scores.items() if score >= 65]
##scores.items()就是把最前面的scores字典拆分成index(人名,Rick Sanchez)和value(70),这样的话就赋值给前面的name,score
print(passed)

#输出
['Beth Smith', 'Summer Smith', 'Rick Sanchez']

你可能感兴趣的:(Udacity,Python,学习指导篇,教学培训)