Python之流程语句:分支、循环、List Comprehension

在Python中,一个程序区块是使用冒号开头,之后同一个区块中要有相同的缩进,不能混用不同的空格数,也不可混用空格和Tab,Python 建议使用4个空格作为缩进。

if分支语句

if condition1:
    if condtion2:
        doSomething()
    else:
        doSomething()
elif condition:
    doSomething()
else:
    doSomething()

Python区块定义的方式避免了像C/C++、Java等语言某些读起来不明确的情况,比如:

if(condition1)
    if(condition2)
        doSomething()
else
    doSomething2()

看起来else好像是跟第一个if语句对应的,但实际上这些语言采用的是就近配对原则,是和第二个if语句对应的,Python中就没有这个问题,是以语句缩进来对应的。

if condition:
    if condition2:
         do_something()
else :
    do_something2()
#else跟第一个if语句配对

if condition:
    if condition2:
         do_something()
    else :
        do_something2()
# else与第二个if配对

在Python中还有个 if...else 表达式:

# 判断奇偶数
>>> num = 11
>>> print('{} 是 {}'.format(num, '奇数' if num % 2 else '偶数'))
11 是 奇数

当if条件满足时,会返回if前面的值,若不满足则返回else后面的值。


while 循环

Python 提供了while 循环,根据while语句后面的内容来判断是否执行循环体:

while condition:
    do_something()
else
    do_something()

当判断条件成立时,会执行while区块,else是可选的,如果有else语句,不管条件成不成立都会执行else下的语句,若不想让else执行就在while区块中加入break语句中断循环,最好还是不要使用,这样容易产生混乱。

print('请输入两个数字')
a = int(input('数字 1 :'))
b = int(input('数字 2 :'))
while b != 0:
    r = a % b
    a = b
    b = r
    if a == 1:
        print('互质')
        break
else:
    print('最大公因数:', a)

还是下面的代码比较直观:

print('请输入两个数字')
a = int(input('数字 1 :'))
b = int(input('数字 2 :'))
while b != 0:
    r = a % b
    a = b
    b = r
    if a == 1:
        print('互质')
    else:
        print('最大公因数:', a)

for in 循环

若要按顺序迭代某个序列(字符串,元组,列表),则可以使用for in 语句:

>>> num = ['a', 1, '2', '3']
>>> for i in num:
...     print(i)
... 
a
1
2
3

如果在迭代的时候需要使用到索引,则可以配合 range() 函数使用,range() 函数可以产生一个指定的数字范围:

>>> for i in range(len(num)):
...     print(i, num[i])
... 
0 a
1 1
2 2
3 3

range() 函数的形式是 range(start, stop[, step]), start默认是0,step是步长默认为1。

也可以使用 zip() 函数,将两个序列的各个元素像拉链一样一一配对,它返回的是一个zip对象,这个对象并没有包含真正配对的元素,具有惰性求值的特性(关于惰性求值请看我的另一篇文章:Python中的优化:惰性求值详解),像range()函数也是产生一个range对象不是列表:

>>> zip([1,2,3],[4,5,6],[7,8,9])
<zip object at 0x108498e08>
>>> for i, j, k in zip([1,2,3],[4,5,6],[7,8,9]):
...     print(i, j, k)
... 
1 4 7
2 5 8
3 6 9

若真的要迭代时具有索引信息,建议使用 enumerate() 函数而不是 range() 函数,enumerate() 返回一个 enumerate 对象,也是惰性求值,可使用for in 进行迭代,enumerate 可用于获取元组元素:

>>> num = [1,2,3,4,5,6]
>>> list(enumerate(num))
[(0, 1), (1, 2), (2, 3), (3, 4), (4, 5), (5, 6)]

可以利用元组拆解的特性获取索引信息:

>>> for i, j in enumerate(num):
...     print(i, j)
... 
0 1
1 2
2 3
3 4
4 5
5 6

只要是实现了__iter__() 方法的对象,都可以通过__iter__() 方法返回一个迭代器,这个迭代器可以使用for in语句来迭代,如:range、zip、enumerate对象,集合也实现了__iter__() 方法,因此也可以进行迭代,但是集合是无序的,每次的迭代结果顺序都不一样;字典也是可以迭代的,使用keys()、values()、items()方法,分别返回dict_keys、dict_values、dict_items对象,也都实现了__iter__() 方法,因此也可以使用for in进行迭代,如果直接对字典进行for in操作,默认对键进行迭代。


pass、break、continue

在某个区块中,并不想执行任何程序语句或者稍后需要些什么语句,对于还没打算编写的区块,可以加上个pass语句,只是用来维持代码的完整性,将来可能会用到它,因为可能会做一些小测试,看看其他的代码是否正常运行。break和continue都是用来跳出循环的,break是直接跳出循环不在进行循环操作,continue是中止本次循环,继续进行下一轮的循环。

list comprehension

将一个列表进行操作转为另外一个列表是很常见的操作,Python提供了 list comprehension 语句:

# 将数组元素平方
#一般做法:
>>> array = [1, 2, 3, 4]
>>> array2 = []
>>> for i in array:
...     array2.append(i ** 2)
... 
>>> print(array2)
[1, 4, 9, 16]
#list comprehension语句
>>> array = [1, 2, 3, 4]
>>> array2 = [i ** 2 for i in array]
>>> print(array2)
[1, 4, 9, 16]

可以看到代码精简了很多,上述语句逐一迭代出数组元素并赋值给i变量,之后执行for左边的表达式运算,使用 [] 括起来,表示每次迭代的结果收集为一个列表。
list comprehension 还可以与条件判断式结合,构成过滤的功能:

#筛选出数组中的奇数
>>> array = [1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]
>>> new_array = [i for i in array if i % 2]
>>> print(new_array)
[1, 3, 5, 7, 9]

在上述代码中,只有满足了if条件才会执行for左边的语句,然后并入数组中。
当然,它还可以嵌套使用,不过这样可读性会变低,简单两层的还可以,复杂的不推荐使用:

# 将二维矩阵转为一维
>>> matrix = [
... [1,2,3],
... [4,5,6],
... [7,8,9]
... ]
>>> array = [e for row in matrix for e in row]
>>> print(array)
[1, 2, 3, 4, 5, 6, 7, 8, 9]

#得到两个序列的排列组合
```python
>>> num1 = [1, 2, 3, 4]
>>> num2 = [1, 2, 3, 4]
>>> [(i ,j) for i in num1 for j in num2 ]
[(1, 1), (1, 2), (1, 3), (1, 4), (2, 1), (2, 2), (2, 3), (2, 4), (3, 1), (3, 2), (3, 3), (3, 4), (4, 1), (4, 2), (4, 3), (4, 4)]
>>> [word1 + word2 for word1 in 'hello' for word2 in 'world']
['hw', 'ho', 'hr', 'hl', 'hd', 'ew', 'eo', 'er', 'el', 'ed', 'lw', 'lo', 'lr', 'll', 'ld', 'lw', 'lo', 'lr', 'll', 'ld', 'ow', 'oo', 'or', 'ol', 'od']

在 list comprehension 两边放上[],会产生列表,如果数据很多,直接返回列表会占用太多内存,可以用() 取代 [] ,这样就会创建一个generator对象,具有惰性求值的特性:

>>> num = (i for i in range(99999999999999999))
>>> num
<generator object <genexpr> at 0x106e29fc0>

list comprehension语句也可以用来创建集合,在语句两边放上{}:

>>> num = [1,2,3,4,5,6,7,8,9,0]
>>> {i for i in num if i % 2}
{1, 3, 5, 7, 9}

也可以用来创建字典,使用zip()函数将键值一一配对:

>>> keys = ['JYH', 'JY']
>>> values = ['123', '456']
>>> {key : value for key, value in zip(keys, values)}
{'JYH': '123', 'JY': '456'}

还可以用来创建元组,由于()会创建生成器,所以要换一种方式,将生成器表达式传给tuple():

>>> tuple(i for i in range(10))
(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)

关于惰性求值请看我的另一篇文章:Python中的优化:惰性求值详解

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,293评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,604评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,958评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,729评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,719评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,630评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,000评论 3 397
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,665评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,909评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,646评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,726评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,400评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,986评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,959评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,996评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,481评论 2 342

推荐阅读更多精彩内容