也许你只是刚刚开始接触python, 也许你已经走上python的不归路,也许你厌倦了条件循环的换行和缩进。To be pythonic, 你不会错过每一个由繁到简的转变。本文简单介绍了python的三元表达式,列表解析式以及它们的结合用法,轻轻松松使用一行代码解决判断与循环,走上pythonic(懒)之路。
三元表达式
在学习python之前你可能已经接触过了三目运算符
判断条件 ? 为真的结果 : 为假的结果
python并没有三目运算符这样的语法,取而代之的是我们的三元表达式
(True) if condition else (False)
举个栗子让我们来看看什么是三元表达式
1 2 3 4 5 6 | >>> a = 5;b = 3 >>> if a > b: ... c = True ... >>> c True |
使用三元表达式
1 2 3 4 | >>> a = 5;b = 3 >>> c = True if a > b else False >>> c True |
或者
1 2 3 | >>> condition =True >>> print( 1 if condition else 0) 1 |
同三目运算符一样, 三元表达式不支持复杂的操作。如果三元表达式支持复杂的操作,那么将所有代码挤到一行里并不是一个明智的选择。那些简单的if statement 才是三元表达式的用武之地。
列表解析式
什么是列表解析式?
列表解析式就是将任何可迭代的对象转换成列表的工具。你可以在转换过程中添加条件进行过滤,
for循环与列表解析式
任何列表解析式都可以改写成for循环,因为其本事就是由for循环构成
举个for循环的栗子:
1 2 3 4 5 6 | >>> a = [] >>> for each in range(5): ... a.append(each) ... >>> a [0, 1, 2, 3, 4] |
如果用了列表解析式,你可以这样写
a = [each for each in range(5)]
嵌套
列表解析式支持for循环嵌套,并且在列表操作上比单纯的for循环更加灵活。
【【 元素 子列表解析式】主列表解析式】
假设我们需要创造一个而5x5的棋盘:
使用for循环并不是那么轻松简单;
1 2 3 4 5 6 7 | >>> board = [] >>> for row in range(5): ... board.append([]) ... for col in range(5): ... board[row].append('+') >>> board [['+', '+', '+', '+', '+'], ['+', '+', '+', '+', '+'], ['+', '+', '+', '+', '+'], ['+', '+', '+', '+', '+'], ['+', '+', '+', '+', '+']] |
注意,如果不太了解python而为数组但有C的经验的话,很可能会写出下面的代码
1 2 3 | for row in range(5): for col in range(5): board[row][col] = '+' |
然而这是不对的,python你并不支持通过定点赋值的方法添加新的列表元素,所以代码显得很臃肿。然而此时你已经掌握了列表解析式的嵌套
1 | >>>board = [['+' for col in range(5)] for row in range(5)] |
现在你变得更pythonic(懒)了。
条件筛选(综合)
如果你想对一个可迭代的对象进行筛选,你就不得不使用for循环来找出每一个子元素并加以判断,大致过程如下:
1 2 3 | for elem in list1: if condition == True: list2.append(elem) |
这样你就可以把所有符合判断条件的list1元素重新组合成新的列表list2中去,举个栗子:
1 2 | >>> secretWord = 'apple' >>> lettersGuessed = ['e', 'i', 'k', 'p', 'r', 's'] |
使用for循环来找出secretWord中重合的字母
1 2 3 4 5 6 | >>> list2 = [] for char in secretWord: if char in lettersGuessed: list2.append(char) >>>list2 ['p', 'p', 'e'] |
忘了告诉你,python中的列表解析式支持条件过滤,格式如下:
[元素 列表解析式 if条件]
有了这个法宝,再回头看我们刚刚的例子
1 2 3 | >>> list2 = [each for each in secretWord if each in lettersGuessed] >>>list2 ['p', 'p', 'e'] |
只要一行,轻轻松松。现在你觉得自己又pythonic(懒)了一分。但是我们现在要做一个猜谜游戏,如果sercretWord中字母不在lettersGuessed 中,我们要用'_'来表示:('_pp_e').然而列表解析式只支持if条件判断并不支持if...else... 好像阻挡了你pythonic(懒)的脚步,但是这是你突然想起了另一样法宝:
三元表达式,然后你把代码写成了这样
1 | list2 = [each for each in secretWord if each in lettersGuessed else '_'] |
然后就报错了,python告诉你语法错误。知道了列表解析式只支持if条件而不是if..else, 而事实证明确实如此
[元素 列表解析式 if条件] == **正确** [元素 列表解析式 if条件else] == **错误**
这是怎么回事,难道三元表达式和列表解析式真的不能双修吗
其实不然,列表解析式挂载的if条件的方式和与三元表达式结合的方式并不一样,前者在后,后者在前:
1 2 3 | >>> list2 = [each if each in lettersGuessed else '_' for each in secretWord] >>> list2 ['_', 'p', 'p', '_', 'e'] |
真是pythonic(懒)极了。
在创建新列表或函数return时,效果极佳。
-- End --