下面从一个名为FizzBuzz的经典编码面试问题入手:
在FizzBuzz中,你将获得一个整数列表,任务是执行以下操作:
1、用“fizz”替换所有可被3整除的整数
2、用“buzz”替换所有可被5整除的整数
3、将所有可被3和5整除的整数替换为“fizzbuzz”
通常情况下,使用range()就能解决此问题:
numbers = [45,22,14,65,97,72]
for i in range(len(numbers)):
if numbers[i] % 3 == 0 and numbers[i] % 5 == 0:
numbers[i] = 'fizzbuzz'
elif numbers[i] % 3 == 0:
numbers[i] = 'fizz'
elif numbers[i] % 5 == 0:
numbers[i] = 'buzz'
但是对于同时获取每个元素的索引和值,更优雅的解决方案使用enumerate():
numbers = [45,22,14,65,97,72]
for i, num in enumerate(numbers):
if num % 3 == 0 and num % 5 == 0:
numbers[i] = 'fizzbuzz'
elif num % 3 == 0:
numbers[i] = 'fizz'
elif num % 5 == 0:
numbers[i] = 'buzz'
对于每个元素,enumerate()返回一个计数器和元素值。关注计数器默认值为0,可以当作元素的索引。
特殊情况:如果索引不想从0开始,可以使用可选参数start参数来设置偏移量。
numbers = [4,2,1,6,9,7]
def square(x):
return x*x
>>list(map(square,numbers))
[16,4,1,36,81,49]
>>[square(x) for x in numbers]
[16, 4, 1, 36, 81, 49]
def is_odd(x):
return bool(x % 2)
...
>>> list(filter(is_odd, numbers))
[1, 9, 7]
>>> [x for x in numbers if is_odd(x)]
[1, 9, 7]
可以看出,递推构造式和其他两个函数返回结果一样,但是列表推导更容易阅读和理解。
但是map()和filter()一般和lambda结合使用,更加方便!
sorted()函数返回一个新的列表,其中值得关注的是可选关键字key,它允许你在排序之前指定将在每个元素上调用的函数。添加函数允许自定义排序规则,对复杂的数据类型进行排序,这些规则特别有用。简单的看个例子:
>>> animals = [
... {'type': 'penguin', 'name': 'Stephanie', 'age': 8},
... {'type': 'elephant', 'name': 'Devon', 'age': 3},
... {'type': 'puma', 'name': 'Moe', 'age': 5},
... ]
>>> sorted(animals, key=lambda animal: animal['age'])
[
{'type': 'elephant', 'name': 'Devon', 'age': 3},
{'type': 'puma', 'name': 'Moe', 'age': 5},
{'type': 'penguin', 'name': 'Stephanie, 'age': 8},
]
通过传入一个返回每个元素年龄的lambda函数,可以轻松地按每个字典的单个值对字典列表进行排序,按年龄进行升序排序。
相比较于列表推导一次性返回所有数据,只需要将[]改为(),就能变成生成器表达式。
生成器表达式返回生成器对象,而不是创建列表。该对象知道它在当前状态中的位置,并且仅在被要求时计算下一个值。
想象一下,你有一个名为cowboy的字典,你想得到那个cowboy的名字。一种方法是使用条件显式检查key:
>>> cowboy = {'age': 32, 'horse': 'mustang', 'hat_size': 'large'}
>>> if 'name' in cowboy:
... name = cowboy['name']
... else:
... name = 'The Man with No Name'
...
>>> name
'The Man with No Name'
此方法首先检查字典中是否存在name键,如果存在,则返回相应的值。否则,它返回默认值。
虽然清楚地检查key确实有效,但如果使用.get(),它可以很容易地用一行代替:
>>> name = cowboy.get('name', 'The Man with No Name')
get()执行与第一种方法相同的操作,但现在它们会自动处理。如果key存在,则返回适当的值。否则,将返回默认值。
但是,如果你想在仍然访问name的key时使用默认值更新字典呢? .get()在这里没有真正帮助你,但Python再次使用.setdefault()提供了更优雅的方法:
>>> name = cowboy.setdefault('name', 'The Man with No Name')
.setdefault()完成与上面代码片段完全相同的操作。它检查cowboy中是否存在名称,如果是,则返回该值。否则,它将cowboy [‘name’]设置为The Man with No Name并返回新值。