关于Python超能力
算是一篇外文Python超能力的读后总结,py的骚操作😂
使用合适的内置函数
1.使用enumerate()代替range()
这个例子我觉得很有意思,找能被3和5整除的数字。
numbers = [1,2,3,4,5,6,6,8,9,10]
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'
print(numbers)
numbers = [1,2,3,4,5,6,6,8,9,10]
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'
print (numbers)
for i, num in enumerate(numbers, start=99):
print(i, num)
help(enumerate)
[1, 2, 'fizz', 4, 'buzz', 'fizz', 'fizz', 8, 'fizz', 'buzz']
[1, 2, 'fizz', 4, 'buzz', 'fizz', 'fizz', 8, 'fizz', 'buzz']
99 1
100 2
101 fizz
102 4
103 buzz
104 fizz
105 fizz
106 8
107 fizz
108 buzz
Help on class enumerate in module builtins:
class enumerate(object)
| enumerate(iterable[, start]) -> iterator for index, value of iterable
|
| Return an enumerate object. iterable must be another object that supports
| iteration. The enumerate object yields pairs containing a count (from
| start, which defaults to zero) and a value yielded by the iterable argument.
| enumerate is useful for obtaining an indexed list:
| (0, seq[0]), (1, seq[1]), (2, seq[2]), ...
|
| Methods defined here:
|
| __getattribute__(self, name, /)
| Return getattr(self, name).
|
| __iter__(self, /)
| Implement iter(self).
|
| __new__(*args, **kwargs) from builtins.type
| Create and return a new object. See help(type) for accurate signature.
|
| __next__(self, /)
| Implement next(self).
|
| __reduce__(...)
| Return state information for pickling.
2.使用列表推导式代替map()和filter()函数
“I think dropping filter() and map() is pretty uncontroversial[.]”
— Guido van Rossum, Python’s creator
上面是Guido说过的一句话体会下。
下面是一个小例子,计算列表中每个元素的平方。
numbers = [1,2,3,4,5,6,7,8]
def square(x):
return x*x
list(map(square, numbers))
[square(x) for x in numbers]
import timeit
print(timeit.timeit("def suquare(x):return x*x;numbers=[1,2,3,4];list(map(square, numbers))",number=10000000))
print(timeit.timeit("def suquare(x):return x*x;numbers=[1,2,3,4];[square(x) for x in numbers]", number=1000000))
0.7148079450125806
0.07825037202565
import timeit
print(timeit.timeit("def is_odd(x):return bool(x%2);numbers=[1,2,3,4,5,6,7,8,9];list(filter(is_odd, numbers))", number=1000000)
)
print(timeit.timeit("def is_odd(x):return bool(x%2);numbers=[1,2,3,4,5,6,7,8,9];[x for x in numbers if is_odd(x)]",number=1000000))
0.1232866600039415
0.08717404800700024
通过时间可以看出来哪个更好一些。
3.使用f格式化字符串
def get_name_and_age():
name = input("Please input you name: ")
age = int(input("Please input you age: "))
return f"Name:{name}-Age:{age}"
get_name_and_age()
Please input you name: jenkins
Please input you age: 10
'Name:jenkins-Age:10'
这样操作真的很耐斯!
4.复杂的列表使用sorted()来排序
animals = [{'type': 'dog', 'name': 'lisa', 'age': 5},
{'type': 'cat', 'name': 'tom', 'age': 10},
{'type': 'bear', 'name': 'jason', 'age': 8}]
sorted(animals, key=lambda animal: animal['age'])
[{'age': 5, 'name': 'lisa', 'type': 'dog'},
{'age': 8, 'name': 'jason', 'type': 'bear'},
{'age': 10, 'name': 'tom', 'type': 'cat'}]
有效的使用数据结构
1.使用集合存储唯一的值
import random
all_words = "all the words in the world!".split()
# get_random_word()
def get_random_word():
return random.choice(all_words)
# Bad Approach
def get_unique_words01():
words = []
for _ in range(1000):
words.append(get_random_word())
return set(words)
print (get_unique_words01())
# Worse Approach
# the time complexity grows on the order of O(N²).
def get_unique_words02():
words = []
for _ in range(1000):
word = get_random_word()
if word not in words:
words.append(word)
return words
print (get_unique_words02())
# Good Approach
def get_unique_words03():
words = set()
for _ in range(1000):
words.add(get_random_word())
return words
print (get_unique_words03())
{'words', 'world!', 'all', 'the', 'in'}
['all', 'in', 'the', 'world!', 'words']
{'words', 'world!', 'all', 'the', 'in'}
从时间复杂度上来看,第三种方法get_unique_words03是个更好的选择。
2.使用生成器来节省内存
import timeit
print(timeit.timeit("[i*i for i in range(1, 1001)]", number=10000))
print(timeit.timeit("(i*i for i in range(1, 1001))", number=10000))
print((timeit.timeit("[i*i for i in range(1, 1001)]", number=10000))/(timeit.timeit("(i*i for i in range(1, 1001))", number=10000)))
type(i*i for i in range(1, 1001))
0.703017319960054
0.008210483007133007
110.22858678442087
generator
generator的魅力很大!
下面是一个斐波那契数列
def fib(max):
n, a, b = 0, 0, 1
while n < max:
yield b
a , b = b, a+b
n = n+1
return 'done'
f=fib(6)
for a in f:
print(a)
下面是一个杨辉三角
def triangles():
L = [1]
yield L
L = [1,1]
yield L
n =2
while True:
n = n+1
T=L
L=[]
L.append(1)
for i in range(1, n-1):
L.append(T[i-1]+T[i])
L.append(1)
yield L
n = 0
results = []
for t in triangles():
print(t)
results.append(t)
n = n + 1
if n == 10:
break
if results == [
[1],
[1, 1],
[1, 2, 1],
[1, 3, 3, 1],
[1, 4, 6, 4, 1],
[1, 5, 10, 10, 5, 1],
[1, 6, 15, 20, 15, 6, 1],
[1, 7, 21, 35, 35, 21, 7, 1],
[1, 8, 28, 56, 70, 56, 28, 8, 1],
[1, 9, 36, 84, 126, 126, 84, 36, 9, 1]
]:
print('测试通过!')
else:
print('测试失败!')
利用python标准库
1.使用collections.defaultdict()处理不存在的字典键
student_grades = {}
grades = [('lisa',88),('lisa',99),('jerry',90),('bill',80)]
for name, grade in grades:
if name not in student_grades:
student_grades[name] = []
student_grades[name].append(grade)
print(student_grades)
from collections import defaultdict
student_grades = defaultdict(list)
for name, grade in grades:
student_grades[name].append(grade)
print(student_grades)
{'lisa': [88, 99], 'jerry': [90], 'bill': [80]}
defaultdict(<class 'list'>, {'lisa': [88, 99], 'jerry': [90], 'bill': [80]})
2.通过collections.Counter计算哈希对象
from collections import Counter
words = "if don't have money, don't have life".split()
counts =Counter(words)
counts
counts.most_common(2)
[("don't", 2), ('have', 2)]
3.使用字符串常量访问公共字符串组
import string
def is_upper(word):
for letter in word:
if letter not in string.ascii_uppercase:
return False
return True
is_upper("Thank you")
is_upper("LOL")
...
True
4.使用itertools生成排列和组合
import itertools
friends =['Lisa','kevin','Tim','Bob']
list(itertools.permutations(friends, r=2))
list(itertools.combinations(friends, r=2))
...
[('Lisa', 'kevin'),
('Lisa', 'Tim'),
('Lisa', 'Bob'),
('kevin', 'Tim'),
('kevin', 'Bob'),
('Tim', 'Bob')]
网友评论