>>> 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]
# 使用map()和列表推导的两种方法都返回相同的值,但列表推导更容易阅读和理解。
>>> 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]
# ,filter和列表推导方法返回相同的值,但列表推导更容易理解。
# 列表推导也支持多个if条件。处在同-循环级别中的多项条件,彼此之间默认形成and表达式。
# 例如,要从数字列表中选出大于4的偶数,那么下面这两种列表推导方式是等效的。
a = [i for i in range(10)]
b = [x for x in a if x>4 if x%2==0]
c = [x for x in a if x>4 and x%2==0]
# 前面提到,列表推导是方便的工具,但有时会导致不必要的内存使用。
# 错误方式
>>> sum([i * i for i in range(1, 1001)])
333833500
# 正确方式
>>> sum((i * i for i in range(1, 1001)))
333833500
# 换出括号会将列表推导更改为生成器表达式。当你知道要从序列中检索数据,但不需要同时访问所有数据的时候,生成器表达式非常适合。
# 生成器表达式返回生成器对象,而不是创建列表。该对象知道它在当前状态中的位置(例如,i = 49)并且仅在被要求时计算下一个值。
# 因此,当sum通过重复调用.__ next __()来迭代生成器对象时,生成器检查i等于多少,计算i * i,在内部递增i,并将正确的值返回到sum。该设计允许生成器用于大量数据序列,因为一次只有一个元素存在于内存中。
def flat(deep_list, result):
for element in deep_list:
if isinstance(element, list):
flat(element, result)
else:
result.append(element)
a = [1, 2, [3, 4, [5, 6, 7], 8], 9, [10, 11]]
result = []
flat(a, result)
print(result)
def list_flat(deep_list, ignore_types=(str, bytes)) -> List:
"""
列表嵌套展平为一维列表
@param deep_list: 嵌套列表
@param ignore_types: 不做展平的类型
@rtype: 一维列表
"""
for element in deep_list:
if isinstance(element, list) and not isinstance(element, ignore_types):
yield from list_flat(element, ignore_types=ignore_types)
else:
yield element
a = [1, 2, [3, 4, [5, 6, 7], 8], 9, [10, 11]]
result = [x for x in list_flat(a)]
print(result)
def map_flat(deep_map, full_key: bool = True) -> Dict:
"""
字典嵌套展平为一维字典
@param deep_map: 嵌套字典
@param full_key: 是否使用完整的key
@rtype: 一维字典
"""
for key, value in deep_map.items():
if isinstance(value, dict):
for k, v in map_flat(value, full_key):
yield (f'{key}_{k}', v) if full_key else (k, v)
else:
yield key, value
from pip._internal import main
main.main(['install', '第三方库名'])
命令行下面的参数都可以通过转换为列表的形式执行,例如:
from pip._internal import main
main.main(['install', '-r', 'requirements.txt'])
使用f-Strings格式化字符串
# f-strings支持使用字符串格式化迷你语言,以及强大的字符串插值。这些功能允许你添加变量甚至有效的Python表达式,并在添加到字符串之前在运行时对它们进行评估:
>>> def get_name_and_decades(name, age):
... return f"My name is {name} and I'm {age / 10:.5f} decades old."
...
>>> get_name_and_decades("Maria", 31)
My name is Maria and I'm 3.10000 decades old.
set 和 frozenset 的实现也依赖散列表,但在它们的散列表里存放的只有元素的引用(就像在字典里只存放键而没有相应的值)。在 set 加入到 Python 之前,我们都是把字典加上无意义的值当作集合来用的。
这些特点总结如下。
集合里的元素必须是可散列的。
集合很消耗内存。
可以很高效地判断元素是否存在于某个集合。
元素的次序取决于被添加到集合里的次序。
往集合里添加元素,可能会改变集合里已有元素的次序。
>>> import random
>>> all_words = "all the words in the world".split()
>>> def get_random_word():
... return random.choice(all_words)
>>> def get_unique_words():
... words = set()
... for _ in range(1000):
... words.add(get_random_word())
... return words
>>> get_unique_words()
{'world', 'all', 'the', 'words'}
使用字符串常量访问公共字符串组
# 可以使用is_upper(),它返回字符串中的所有字符是否都是大写字母:
>>> import string
>>> def is_upper(word):
... for letter in word:
... if letter not in string.ascii_uppercase:
... return False
... return True
...
>>> is_upper('Thanks Geir')
False
>>> is_upper('LOL')
True
# is_upper()迭代word中的字母,并检查字母是否为string.ascii_大写字母的一部分。如果你打印出string.ascii_大写,你会发现它只是一个字符串,该值设置为文本“ABCDEFGHIJKLMNOPQRSTUVWXYZ”。
所有字符串常量都只是经常引用的字符串值的字符串。其中包括以下内容:
string.ascii_letters
string.ascii_uppercase
string.ascii_lowercase
string.digits
string.hexdigits
string.octdigits
string.punctuation
string.printable
string.whitespace
在这些语句中使用 else 子句通常能让代码更易于阅读,而且能省去一些麻烦,不用设置控制标志或者添加额外的 if 语句。
# for else 是 Python 中特有的语法格式,else 中的代码在 for 循环遍历完所有元素之后执行
# 如果for循环正常结束,else中语句执行。如果是break的,则不执行。
for i in mylist:
if i == theflag:
break
process(i)
else:
raise ValueError("List argument missing terminal flag.")
# 方式一
flag = False
for x in xx:
if some condition:
flag = True
break
if flag:
print 'no break'
# 方式二
for x in xx:
if some condition:
break
else:
print 'no break'
# 判断质数/素数——我知道的最快的方法
# https://blog.csdn.net/songyunli1111/article/details/78690447
# Example
def is_prime(n = 20):
is_p = False
for ii in range(2 if n>=2 else 1, int(math.sqrt(n))+1):
if n%ii == 0:
break
else:
is_p = True
return is_p
# 或者直接写成
def is_prime(n = 20):
for ii in range(2 if n>=2 else 1, int(math.sqrt(n))+1):
if n%ii == 0:
return False
else:
return True
# 获取n=50以内的素数列表
import math
n = 50
data = [ii for ii in range(n)]
res = itertools.compress(data,[is_prime(da) for da in data])
print([r for r in res])
Out[30]: [0, 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47]
# 未使用__slots__
# -*- coding: utf-8 -*
from memory_profiler import profile
class Foobar(object):
# __slots__ = ('x')
def __init__(self, x):
self.x = x
@profile
def main():
f = [Foobar(42) for i in range(1000000)]
if __name__ == "__main__":
main()
Line # Mem usage Increment Line Contents
================================================
137 45.7 MiB 45.7 MiB @profile
138 def main():
139 215.9 MiB 0.9 MiB f = [Foobar(42) for i in range(1000000)]
# 使用__slots__
# -*- coding: utf-8 -*
from memory_profiler import profile
class Foobar(object):
__slots__ = ('x')
def __init__(self, x):
self.x = x
@profile
def main():
f = [Foobar(42) for i in range(1000000)]
if __name__ == "__main__":
main()
Line # Mem usage Increment Line Contents
================================================
132 45.7 MiB 45.7 MiB @profile
133 def main():
134 99.8 MiB 0.4 MiB f = [Foobar(42) for i in range(1000000)]