Effective Python (Second Edition) 笔记——培养Pythonic思维

目录

4、用支持插值的 f-string

5、用辅助函数取代复杂的表达式

6、把数据结构直接拆分到多个变量里,不要专门通过下标访问

7、尽量用 enumerate 取代 range

8、用 zip 函数同时遍历两个迭代器


4、用支持插值的 f-string

  • f-string是个简洁而强大的机制,可以直接在格式说明符里嵌入任意Python表达式。
key = 'my_var'
value = 1.234

formatted = f'{key!r:<10} = {value:.2f}'
print(formatted)

-------------------------------------------
>>> 'my_var'     = 1.23
places = 3
number = 1.23456

print(f'My number is {number:.{places}f}')

--------------------------------------------
>>> My number is 1.235

5、用辅助函数取代复杂的表达式

  • 尤其是重复使用的复杂表达式,应该写到辅助函数里面。
  • 用 if / else 结构写成的条件表达式,要比用 or 与 and 写成的 Boolean 表达式更好懂。
  • dict_name.get(key_name, exception_to_return) 的方式可以返回不存在的键,并返回设定的值。
def get_first_int(values, key, default=0):
    found = values.get(key, [''])
    if found[0]:
        return int(found[0])
    return default

6、把数据结构直接拆分多个变量里,不要专门通过下标访问

  • 凡是可迭代的对象都能拆分,无论里面还有多少层迭代结构。
  • 尽量通过 unpacking 来拆解序列之中的数据。
item = ('Peanut butter', 'Jelly')
first, second = item  # 左边可以是list, sequence, iterable
print(first, 'and', second)

-------------------------------------------------------------
>>> Peanut butter and Jelly

7、尽量用 enumerate 取代 range

  • 可以通过 enumerate 的第二个参数指定起始序号(默认为0)
  • enumerate 能把任何一种 iterator 封装成 lazy generator,每次循环的时候,只需要从 iterator 里面获取下一个值就可以,同时还会给出本轮循环的序号。可以通过内置的 next 函数手动推进 enumerate 所返回的这个 iterator。next(enumerate(flavor_list))
for i, flavor in enumerate(flavor_list):
    print(f'{i + 1}: {flavor}')

for i, flavor in enumerate(flavor_list, 1):
    print(f'{i}: {flavor}')

--------------------------------------------
>>> 1: vanilla
    2: chocolate
    3: pecan
    4: strawberry

8、用 zip 函数同时遍历两个迭代器

  • 如果无法确定列表的长度相同,就不要传给 zip,而是传给 zip_longest 函数,这个函数位于内置的 itertools 模块里。
  • zip 函数能够把两个或更多的 iterator 封装成 lazy generator,每次循环时,会分别从这些迭代器里获取各自的下一个元素,并把这些值放在一个元组里面,而这个元组可以拆分到 for 语句里那些变量中。
  • zip 每次只从它封装的那些迭代器里各自取出一个元素,所以即便源列表很长,程序也不会因为占用内存过多而崩溃。
  • 如果提供的迭代器长度不一致,其中任何一个完毕,zip 就会停止。
for name, count in zip(names, counts):
    if count > max_count:
        longest_name = name
        max_count = count
import itertools

for name, count in itertools.zip_longest(names, counts):
    print(f'{name}: {count}')

9、不要forwhile 循环后面else

  • for / else 结构里的 else,如果循环从头到尾执行完,那就执行 else 块。在循环中使用 break 语句实际上会跳过 else 块。
  • 如果对空白序列做 for 循环,那么程序立刻就会执行 else 块。
  • while 循环同上,首次循环就遇到 False,会立刻执行 else 块。
  • 如果把 else 块紧跟在 for / while 的后面,就会让代码产生歧义。
a = 4
b = 9

for i in range(2, min(a, b) + 1):
    print('Testing', i)
    if a % i == 0 and b % i == 0:
        print('Not coprime')
        break
else:
    print('Coprime')

-------------------------------------
>>> Testing 2
    Testing 3
    Testing 4
    Coprime

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值