Python 基础学习07:条件与循环

回到 print 和 import

print 是一个内置函数,提供了多种参数:

print(*args, sep=' ', end='\n', file=None, flush=False)
    Prints the values to a stream, or to sys.stdout by default.

    sep
      string inserted between values, default a space.
    end
      string appended after the last value, default a newline.
    file
      a file-like object (stream); defaults to the current sys.stdout.
    flush
      whether to forcibly flush the stream.

*args 表明 print 支持打印多个参数:

print('Hello', 'World')
Hello World

sep 代表多个参数之间的间隔符,默认为空格:

print('Hello', 'World', sep='--')
Hello--World

end 代表打印参数后在最后添加的内容,默认是换行:

print('Hello', 'World', sep='--', end='#This is end.')
Hello--World#This is end.

导入时重命名

导入模块时使用 import somemodule 时,会将该模块中的所有方法导入,使用时通过 modulename.functionname 方式使用。
使用 from somemodule import somefunction, anotherfunction .. 方式导入时,可直接使用 functionname 使用。
如果确定要导入模块中的一切式,使用 from somemodule import * 方式导入。

如果不同模块中的函数名称冲突,可以使用 as 来指定别名:

from math import pi as p
p
3.141592653589793

赋值魔法

赋值语句也存在一些有趣高效的方法。

序列解包

序列解包:将一个序列(或任何可迭代对象)解包,并将得到的值存储到一系列变量中。

data = [1,2,3]
x, y, z = data
print(x, y, z, sep='-')
1-2-3

使用返回元组(或其它序列或可迭代对象)的函数和方法时很有用:

data = {'name': 'imxcai', 'blog': 'www.imxcai.com'}
x, y = data.popitem()
print(x, y, sep='/')
blog/www.imxcai.com

要解包序列包含的的元素个数应与等号一侧的目标个数相同,否则将引发异常:

a,b,c = [1,2,3,4]
Traceback (most recent call last):
  File "<pyshell#103>", line 1, in <module>
    a,b,c = [1,2,3,4]
ValueError: too many values to unpack (expected 3)

可以使用 * 来收集多余的值:

a,b,*c = [1,2,3,4]
c
[3, 4]

*a,b,c = [1,2,3,4]
a
[1, 2]

带星号的变量可以放在任意位置,且最终返回的始终是一个列表:

a, b, *c = [1,2,3]
c
[3]

链式赋值

链式赋值是一种快捷方式,用于将多个变量关联到同一个值:

x = y = somefunction()

等效于:

y = somefouncation()
x = y

不等效于:

x = somefouncation()
y = somefouncation()

增强赋值

x = x + 1 可以将右边表达式中的运算符号移到赋值运算符(=) 的前面,变成 x += 1 这称为增强赋值,适用于所有标准运算符。
增强赋值也可以用于其它数据类型:

str = 'foo'
str += 'bar'
str
'foobar'
str *= 2
str
'foobarfoobar'

条件和条件语句

条件语句是让程序是否指定特定的语句块。

布尔值

标准值 False 和 None、各种类型(包括浮点数、复数)的数值 0 、空序列(空字符串、空元组和空列表)和空映射(空字典)都被视为假,而其它各种值都被视为真,包括特殊值 True。任何值都可以用 bool() 进行转换:

bool('abc')
True
bool(1)
True
bool([])
False

有条件的执行和 if 语句

if 语句能够有条件的执行代码,如果条件为真,就执行后续的代码,如果为假则不执行:

name = 'Bob Gumby'
if name.endswith('Gumby'):
    print('Hello Gumby')


Hello Gumby

else 子句

else 子句为 if 条件为假时指定了要执行的语句:

name = 'Bob Gumby'
if name.endswith('bob'):
    print('Hello bob')
else:
    print('Welcome!')


Welcome!

elif 语句

elif 是 else if 的缩写,可用于检查多个条件:

num = int(input('Enter a number: '))
if num > 0:
    print('The number is positive')
elif num < 0:
    print('The number is negative')
else:
    print('The number is zero')

更复杂的条件

if 语句中,条件本身很重要。

比较运算符

条件表达式中,最基本的运算符是比较运算符,用于执行比较。

表达式描述
x == yx 等于 y
x < yx 小于 y
x > yx 大于 y
x >= yx 大于等于 y
x <= yx 小于等于 y
x != yx 不等于 y
x is yx 和 y 是同一对象
x is not yx 和 y 不是同一对象
x in yx 是容器 y 的成员
x not in yx 不是容器 y 的成员

与赋值一样,也支持链式比较,如 0 < age < 100

布尔运算符

and 是一个布尔运算符,它接受两个真值,并在两个都为真时才返回真,否则返回假。
另外还有 ornot 这两个布尔运算符。

if ((cash > price) or customer_has_good_credit) and not out_of_stock:
    give_goods()

断言

让程序在错误条件出现后立即崩溃胜过以后再崩溃。
如果知道必须满足特定条件,程序才能正确的运行,可在程序里面添加 assert 语句充当检查点。
assert 可在条件后面添加一个字符串,用于说明:

age = -1
assert 0 < age < 100 , 'The age must be realistic!'
Traceback (most recent call last):
  File "<pyshell#154>", line 1, in <module>
    assert 0 < age < 100 , 'The age must be realistic!'
AssertionError: The age must be realistic!

循环

循环用于重复操作多次,执行周期性的任务。

while 循环

while 循环的格式如下:

x = 1
while x <= 100:
    print(x)
    x += 1

如果条件为 True 则一直循环。

for 循环

为序列(或其它可迭代对象)中的每个元素执行代码块可使用 for 循环:

data = [1,2,3,4,5]
for d in data:
    print(d)

遍历是特定范围内的数,这是一种常见的任务,Python 提供了创建范围的内置函数 range :

range(0,10)
range(0, 10)
type(range(0,10))
<class 'range'>

返回的是一个可迭代的对象,可直接进行迭代循环:

for i in range(0,3):
    print(i)


0
1
2

也可以通过 list 转换为列表:

data = list(range(0,3))
data
[0, 1, 2]

迭代字典

迭代字典有两种方式,一种方式是迭代出 key 然后根据 key 获取 value

d = {'a': 'alice', 'b': 'bob', 'c': 'caer'}
for k in d:
    print(k, '---', d[k])


a --- alice
b --- bob
c --- caer

另一种是通过 items 返回元组,然后通过序列解包的方式:

d = {'a': 'alice', 'b': 'bob', 'c': 'caer'}
for k, v in d.items():
    print(k, '----', v)


a ---- alice
b ---- bob
c ---- caer

迭代工具

Python 提供了多个可帮助进行迭代序列的函数。

并行迭代

同时迭代两个序列,可用的方式有:

a = [1,2,3]
b = ['a','b','c']

for i in range(len(a)):
    print(a[i], '---', b[i])


1 --- a
2 --- b
3 --- c

此外还可使用 zip 函数,该函数可以缝合任意数量的序列,当序列长度不同时,将在最短的序列用完后停止缝合:

a = [1,2,3]
b = ['a','b','c']
zip(a,b)
<zip object at 0x7f5ec92f95c0>
for x,y in zip(a,b):
    print(x, y,sep='---')


1---a
2---b
3---c

list(zip(range(3),range(10000)))
[(0, 0), (1, 1), (2, 2)]

迭代时获取索引

内置函数 enumerate 能够迭代索引-值对,索引是自动提供的:

enumerate('abc')
<enumerate object at 0x7f5ec75c3380>
list(enumerate('abc'))
[(0, 'a'), (1, 'b'), (2, 'c')]

迭代循环时可以很容易的获取到索引:

strings = 'helloworld'
for index, string in enumerate(strings):
    if string == 'w':
        print('index is:', index, 'string is: ', string)


index is: 5 string is:  w

反向迭代和排序后迭代

内置的函数 reversedsorted 类似于列表方法中的 reversesort ,但这两个函数可以用于任何序列或可迭代的对象,且不就地修改对象,而是返回反转和排序后的版本。

sorted([2,5,1,8,4])
[1, 2, 4, 5, 8]
reversed('hello')
<reversed object at 0x7f5ec86f12a0>
list(reversed('hello'))
['o', 'l', 'l', 'e', 'h']

跳出循环

通常循环会不断的执行代码块,直到条件为假或使用完序列中的所有元素,但在有些情况下可以控制中断循环或进入新的一个循环。

break

要结束循环,可使用 break,但执行到 break 语句时,将结束整个的循环:

for i in range(10000):
    print(i)
    if i == 1:
        break


0
1

continue

continue 用于结束当前的迭代,并跳到下一个迭代的开头:

for i in range(0,10):
    if i % 2 == 0:
        continue
    print(i)


1
3
5
7
9

while True/break 成例

while True 会导致循环永不结束,但可以在满足条件中的 if 语句中放置 break

while True:
    word = input('Pls input some words: ')
    if not word: break
    print('The word was: ', word)

循环中的 else 子句

如何判断循环是提前结束还是正在结束呢?简单的方法是在循环外添加一条 else 子句,仅在没有调用 break 时才执行:

from math import sqrt
for n in range(99, 81, -1):
    root = sqrt(n)
    if root == int(root):
        print(n)
        break
else:
    print("Didn't find it!")

简单推导

列表推导是一种从其它列表创建列表的方式,列表推导的工作原理类似于 for 循环:

[ x * x for x in range(10) ]
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

推导中还可以使用 if 语句来生成满足条件的元素:

[ x * x for x in range(10) if x % 3 == 0]
[0, 9, 36, 81]

添加更多的 for 结构:

[ (x, y) for x in range(3) for y in range(3) ]
[(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)]

同样,也可使用 if 语句:

[ (x, y) for x in range(3) for y in range(3) if x == y ]
[(0, 0), (1, 1), (2, 2)]

使用圆括号不能实现元组的推导,而是创建生成器。
但是可以使用花括号来执行字典的推导:

sqrts = { i: "{} squartd is {}".format(i, i**2) for i in range(10)}
sqrts[6]
'6 squartd is 36'

在列表推导中,for 前面只有一个表达式,在字典推导中,for 前面有两个用冒号分隔的表达式,两个表达式分别为键和对应的值。

三人行

passdelexec 语句的使用。

什么都不做

pass 语句代表什么都不做,通常用于占位符。

if True:
    pass

如果 if 中没有任何可执行的代码,程序将报错,此时可以使用 pass 语句。

使用 del 删除

对于没有任何变量或数据结构指向的对象,Python 通常会将其删除。
del 语句会删除对象的引用,还会删除名称本身:

x = 1
del x
x
Traceback (most recent call last):
  File "<pyshell#90>", line 1, in <module>
    x
NameError: name 'x' is not defined

但是 del 不会删除对象本身,只会删除名称和引用:

y = x = 1
del x
x
Traceback (most recent call last):
  File "<pyshell#93>", line 1, in <module>
    x
NameError: name 'x' is not defined
y
1

Python 中没有办法删除值,也不需要删除,但一个值没有任何引用时(不再使用),会被 Python 自动回收,立即删除。

使用 exec 和 eval 执行字符串

execeval 是内置函数,可以动态的执行 Python 代码,能够将其作为语句进行或作为表达式进行计算。

exec

函数 exec 将字符串作为代码执行:

exec("print('hi')")
hi

大多数情况下,还应向它传递一个命名空间,命名空间是存放变量的地方,防止输入的代码污染命名空间,如修改之前定义的变量。
没有命名空间的情况:

from math import sqrt
type(sqrt)
<class 'builtin_function_or_method'>
exec("sqrt=1")
type(sqrt)
<class 'int'>
sqrt(4)
Traceback (most recent call last):
  File "<pyshell#113>", line 1, in <module>
    sqrt(4)
TypeError: 'int' object is not callable

动态执行的 exec 函数,将 sqrt 内置函数覆盖成了一个变量,导致后续使用函数报错。
exec 传递第二个字典类型的参数,用作代码字符串的命名空间:

from math import sqrt
scope = {}
exec('sqrt = 1', scope)
sqrt(4)
2.0
scope['sqrt']
1

scope 中还包含一个自动添加了所有内置函数和值的字典 __builtins__

scope.keys()
dict_keys(['__builtins__', 'sqrt'])

eval

exec 是执行一系列 Python 语句,eval 计算用字符串表示的 Python 表达式的值,并返回结果(exec 不返回结果,其本身就是条语句)。

eval(input(" Enter an artihmetic expression: "))
 Enter an artihmetic expression: 10*5 + 20
70

exec 一样, eval 也可以添加命名空间,命名空间中可以提前放置一些值:

scope = {}
scope['x'] = 2
scope['y'] = 3
eval('x * y', scope)
6

发表评论

您的邮箱地址不会被公开。 必填项已用 * 标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据

滚动至顶部