Python核心与实战学习笔记(五):条件与循环

5.1 条件语句

在使用条件语句时,很多人喜欢省略判断条件:

if s: # s is a string
    ...
if l: # l is a list
    ...
if i: # i is an int
    ...
... 

在这里插入图片描述
不过,在实际代码写代码时,还是不鼓励省略判断条件的写法(除了Boolean类型),条件判断最好是显性的。比如,在判断整型数是否为0时,最好写出判断的条件:

if i != 0:
    ...

而不是只写出变量名:

if i:
    ...

5.2 循环语句

通过循环语句可以遍历可迭代(iterable)的数据结构。
对于字典,只有键是可迭代的。如果要遍历值,则需要用到字典的内置函数dict.values();遍历键值对则需用到dict.items()

d = {'name': 'jason', 'dob': '2000-01-01', 'gender': 'male'}
for k in d: # 遍历字典的键
    print(k)
name
dob
gender

for v in d.values(): # 遍历字典的值
    print(v)
jason
2000-01-01
male    

for k, v in d.items(): # 遍历字典的键值对
    print('key: {}, value: {}'.format(k, v))
key: name, value: jason
key: dob, value: 2000-01-01
key: gender, value: male 

善用enumerate(<iterable>)函数

善用continue

在循环中,适当使用continue能使代码更简洁。

比如,给定两个字典,分别是产品名称到价格的映射,和产品名称到颜色列表的映射。我们要找出价格小于 1000,并且颜色不是红色的所有产品名称和颜色的组合。如果不用 continue,代码应该是下面这样的:

# name_price: 产品名称 (str) 到价格 (int) 的映射字典
# name_color: 产品名字 (str) 到颜色 (list of str) 的映射字典
for name, price in name_price.items():
    if price < 1000:
        if name in name_color:
            for color in name_color[name]:
                if color != 'red':
                    print('name: {}, color: {}'.format(name, color))
        else:
            print('name: {}, color: {}'.format(name, 'None'))

使用了continue之后,代码更加清晰:

# name_price: 产品名称 (str) 到价格 (int) 的映射字典
# name_color: 产品名字 (str) 到颜色 (list of str) 的映射字典
for name, price in name_price.items():
    if price >= 1000:
        continue
    if name not in name_color:
        print('name: {}, color: {}'.format(name, 'None'))
        continue
    for color in name_color[name]:
        if color == 'red':
            continue
        print('name: {}, color: {}'.format(name, color))

第一种写法有5层for或if的嵌套,第二种写法只有3层嵌套。多重嵌套会使得代码冗余、难读,也不利于后续的调试、修改。因此要尽量避免多层嵌套

5.3 效率比较

对于遍历,有以下两种写法:

i = 0
while i < 1000000:
    i += 1
for i in range(0, 1000000):
    pass

第二种写法的效率更快,原因是:range()是C函数写的可以直接调用;而i+1操作得通过python解释器间接调用底层的C语言,而且还涉及到了对象的创建和删除(因为i是整型,是immutable,相当于i = new int(i+1))

5.4 循环进阶:一行代码写多重循环

1.判断条件中有else

expression1 if condition else expression2 for item in iterable

等价于:

for item in iterable:
    if condition:
        expression1
    else:
        expression2
  1. 判断条件中没有else
expression for item in iterable if condition

示例1:
对于函数y = 2*|x| + 5,给定集合x的数据点,需要计算出y的数据集合,则可使用下面一行语句完成:

y = [value*2 + 5 if value > 0 else -value * 2 + 5 for value in x]

示例2:
对于一个字符串,去掉空格以及字母少于3的单词:
方法1:

import re 
words = ' Today, is , Sunday,I think you could be happy.'
wordlist = re.findall(r'\w+', words)
result = [x for x in wordlist if len(x)>=3]
=====================================================
['Today', 'Sunday', 'think', 'you', 'could', 'happy']

方法2:

words = ' Today, is , Sunday,I ,think, you ,could, be, happy'
result = [word.strip() for word in words.split(',') if len(word.strip())>=3] 
===================================
['Today', 'Sunday', 'think', 'you', 'could', 'happy']
  1. 双重循环写一行
[(xx, yy) for xx in x for yy in y if xx != yy]

等价于:

l = []
for xx in x:
    for yy in y:
        if xx != yy:
            l.append((xx, yy))

熟练之后,这种写法会非常方便。

5.5 总结

在这里插入图片描述

5.6 思考题

给定下面两个列表 attributes 和 values,要求针对 values 中每一组子列表 value,输出其和 attributes中的键对应后的字典,最后返回字典组成的列表。

attributes = ['name', 'dob', 'gender']
values = [['jason', '2000-01-01', 'male'], 
['mike', '1999-01-01', 'male'],
['nancy', '2001-02-01', 'female']
]

# expected outout:
[{'name': 'jason', 'dob': '2000-01-01', 'gender': 'male'}, 
{'name': 'mike', 'dob': '1999-01-01', 'gender': 'male'}, 
{'name': 'nancy', 'dob': '2001-02-01', 'gender': 'female'}]

多行代码

attributes = ['name', 'dob', 'gender']
values = [['jason', '2000-01-01', 'male'], 
['mike', '1999-01-01', 'male'],
['nancy', '2001-02-01', 'female']
]
result = []
for value in values:
    person = {}
    for index,attr in enumerate(attributes):
        person[attr] = value[index]

    result.append(person)

一行代码

注意到attributes数组的元素个数和values的元素value的元素个数相同,则可使用同一个索引下标:

result = [{attributes[index]:value[index] for index in range(len(attributes))} for value in values]

注意到attributes数组的元素个数和values的元素value的元素个数相同,则可利用zip()函数直接打包

result = [dict(zip(attributes,value)) for value in values]
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值