原标题:优雅编写Python3的62个小贴士!
作者 | QIML编辑部
来源 | 量化投资与机器学习(ID:Lhtz_Jqxx)
今天公众号为大家带来一篇有关Python技巧的文章,可以帮助你编写优雅的Python3代码!
iterable技巧
▍1、创建一个数字序列(从0到10,间隔为2)
>>>range(0,10,2)
[0, 2, 4, 6, 8]
▍2、对一串数字求和(从0到10,间隔为2)
>>>l = range(0,10,2)
>>>sum(l)
20
▍3、检查序列中的任一元素是否为True
>>>any(a % 2fora inrange(0,10,2))
True
▍4、检查序列中的所有元素是否为True
>>>all(a % 2fora inrange(0,10,2))
True
▍5、累计求和一串数字序列
>>>importnumpy asnp
>>>res = list(np.cumsum(range(0,10,2)))
>>>res
[ 0, 2, 6, 12, 20]
▍6、给定每个iterable,通过添加索引来构造一个元组
>>>a = ['Hello', 'world', '!']
>>>list(enumerate(a))
[(0, 'Hello'), (1, 'world'), (2, '!')]
▍7、将iterable连接到单个字符串
>>>a = ["python","really", "rocks"]
>>>" ".join(a)
'python really rocks'
▍8、组合两个可迭代的元组或pivot嵌套的iterables
# Combining two iterables
>>>a = [1, 2, 3]
>>>b = ['a', 'b', 'c']
>>>z = zip(a, b)
>>>z
[(1, 'a'), (2, 'b'), (3, 'c')]
# Pivoting list of tuples
>>>zip(*z)
[(1, 2, 3), ('a', 'b', 'c')]
▍9、从iterables中获取最小值/最大值(具有/不具有特定功能)
# Getting maximum from iterable
>>>a = [1, 2, -3]
>>>max(a)
2
# Getting maximum from iterable
>>>min(a)
1
# Bot min/max has key value to allow to get maximum by appliing function
>>>max(a,key=abs)
3
▍10、可迭代排序(可以通过“compare”函数排序)
>>>a = [1, 2, -3]
>>>sorted(a)
[-3, 1, 2]
>>>sorted(a,key=abs)
[1, 2, -3]
▍11、将单个字符串拆分为列表
>>>s = "a,b,c"
>>>s.split(",")
["a", "b", "c"]
▍12、初始化一个包含重复数字的列表
>> [1]* 10
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
▍13、合并/插入两个字典
>>>a = {"a":1, "b":1}
>>>b = {"b":2, "c":1}
>>>a.update(b)
>>>a
{"a":1, "b":2, "c":1}
▍14、命名和保存iterables切片
# Naming slices (slice(start, end, step))
>>>a = [0, 1, 2, 3, 4, 5]
>>>LASTTHREE = slice(-3, None)
>>>LASTTHREE
slice(-3, None, None)
>>>a[LASTTHREE]
[3, 4, 5]
▍15、在列表中查找项的索引
>>>a = ["foo", "bar", "baz"]
>>>a.index("bar")
1
▍16、在iterables中查找最小/最大项的索引
>>>a = [2, 3, 1]
>>>min(enumerate(a),key=lambdax: x[1])[0]
2
▍17、iterables的k个元素
>>>a = [1, 2, 3, 4]
>>>k = 2
>>>a[-2:] + a[:-2]
[3, 4, 1, 2]
▍18、删除字符串末尾/开始/两端无用的字符
>>>name = "//George//"
>>>name.strip("/")
'George'
>>>name.rstrip("/")
'//George'
>>>name.lstrip("/")
'George//'
▍19、倒序iterables的顺序(字符串、列表等)
# Reversing string
>>>s = "abc"
>>>s[::-1]
"cba"
# Reversing list
>>>l = ["a", "b", "c"]
>>>l[::-1]
["c", "b", "a"]
branching技巧
▍20、多个short-cut
>>>n = 10
>>>1< n < 20
True
▍21、For-else结构在搜索某些东西并找到它时很有用
fori inmylist:
ifi == theflag:
break
process(i)
else:
raiseValueError("List argument missing terminal flag.")
▍22、Trenary operator
>>>"Python ROCK"ifTrueelse" I AM GRUMPY"
"Python ROCK"
▍23、Try-catch-else结构
try:
foo
exceptException:
print("Exception occured")
else:
print("Exception didnt occur")
finally:
print("Always gets here")
▍24、While-else结构
i = 5
whilei > 1:
print("Whil-ing away!")
i -= 1
ifi == 3:
break
else:
print("Finished up!")
comprehensions(推导式)技巧
▍25、List推导式
>>>m = [x ** 2forx inrange(5)]
>>>m
[0, 1, 4, 9, 16]
▍26、Set推导式
>>>m = {x ** 2forx inrange(5)}
>>>m
{0, 1, 4, 9, 16}
▍27、Dict推导式
>>>m = {x: x ** 2forx inrange(5)}
>>>m
{0: 0, 1: 1, 2: 4, 3: 9, 4: 16}
▍28、Generator推导式
# A generator comprehension is the lazy version of a list comprehension.
>>>m = (x ** 2forx inrange(5))
>>>m
at 0x108efe408>
>>>list(m)
[0, 1, 4, 9, 16]
>>>m = (x ** 2forx inrange(5))
>>>next(m)
0
>>>list(m)
[1, 4, 9, 16]
▍29、list推导使用当前值和过往值
>>>a = [1, 2, 4,2]
>>>[y - x forx,y inzip(a,a[1:])]
[1, 2, -2]
unpacking技巧
▍30、从iterable解压缩变量
# One can unpack all iterables (tuples, list etc)
>>>a, b, c = 1, 2, 3
>>>a, b, c
(1, 2, 3)
>>>a, b, c = [1, 2, 3]
>>>a, b, c
(1, 2, 3)
▍31、交换变量值
>>>a, b = 1, 2
>>>a, b = b, a
>>>a, b
(2, 1)
▍32、在不指示所有元素的情况下从iterable解包变量
>>>a, *b, c = [1, 2, 3, 4, 5]
>>>a
1
>>>b
[2, 3, 4]
>>>c
5
▍33、使用splat运算符解包变量
>>>deftest(x, y, z):
>>>print(x, y, z)
>>>res = test(*[10, 20, 30])
102030
>>>res = test(**{'x': 1, 'y': 2, 'z': 3} )
102030
view raw
Itertools技巧
▍34、Flatten iterables
>>>a = [[1, 2], [3, 4], [5, 6]]
>>>list(itertools.chain.from_iterable(a))
[1, 2, 3, 4, 5, 6]
▍35、从iterables创建笛卡尔积
>>>forp initertools.product([1, 2, 3], [4, 5]):
>>>print(''.join(str(x) forx inp))
(1, 4)
(1, 5)
(2, 4)
(2, 5)
(3, 4)
(3, 5)
▍36、从iterable创建排列
>>>forp initertools.permutations([1, 2, 3, 4]):
>>>print(''.join(str(x) forx inp))
123
132
213
231
312
321
▍37、从iterable创建ngram
>>>fromitertools importislice
>>>defn_grams(a, n):
...z = (islice(a, i, None) fori inrange(n))
...returnzip(*z)
...
>>>a = [1, 2, 3, 4, 5, 6]
>>>n_grams(a, 3)
[(1, 2, 3), (2, 3, 4), (3, 4, 5), (4, 5, 6)]
>>>n_grams(a, 2)
[(1, 2), (2, 3), (3, 4), (4, 5), (5, 6)]
>>>n_grams(a, 4)
[(1, 2, 3, 4), (2, 3, 4, 5), (3, 4, 5, 6)]
▍38、使用填充组合元组的两个迭代器或使用填充pivot嵌套迭代
>>>importitertools asit
>>>x = [1, 2, 3, 4, 5]
>>>y = ['a', 'b', 'c']
>>>list(zip(x, y))
[(1, 'a'), (2, 'b'), (3, 'c')]
>>>list(it.zip_longest(x, y))
[(1, 'a'), (2, 'b'), (3, 'c'), (4, None), (5, None)]
▍39、从一个iterable n中创建k个组合
>>>importitertools
>>>bills = [20, 20, 20, 10, 10, 10, 10, 10, 5, 5, 1, 1, 1, 1, 1]
>>>list(itertools.combinations(bills, 3))
[(20, 20, 20), (20, 20, 10), (20, 20, 10), ... ]
▍40、在给定函数情况下创建一个迭代的累积结果
>>>importitertools
>>>list(itertools.accumulate([9, 21, 17, 5, 11, 12, 2, 6], min))
[9, 9, 9, 5, 5, 5, 2, 2]
▍41、创建一个迭代器,只要谓词为True,就从iterable返回元素
>>>importitertools
>>>itertools.takewhile(lambdax: x < 3, [0, 1, 2, 3, 4])
[0, 1, 2]
>>>it.dropwhile(lambdax: x < 3, [0, 1, 2, 3, 4])
[3, 4]
▍42、创建一个迭代器,它从iterable中过滤元素,只返回谓词为False的元素
>>>importitertools
# keeping only false values
>>>list(itertools.filterfalse(bool, [None, False, 1, 0, 10]))
[None, False, 0]
使用从迭代的迭代中获得的参数来计算函数
>>>importitertools
>>>importoperator
>>>a = [(2, 6), (8, 4), (7, 3)]
>>>list(itertools.starmap(operator.mul, a))
[12, 32, 21]
collections技巧
▍44、设置基本操作
>>>A = {1, 2, 3, 3}
>>>A
set([1, 2, 3])
>>>B = {3, 4, 5, 6, 7}
>>>B
set([3, 4, 5, 6, 7])
>>>A | B
set([1, 2, 3, 4, 5, 6, 7])
>>>A & B
set([3])
>>>A - B
set([1, 2])
>>>B - A
set([4, 5, 6, 7])
>>>A ^ B
set([1, 2, 4, 5, 6, 7])
>>>(A ^ B) == ((A - B) | (B - A))
True
▍45、计数器数据结构(无序集合,其中元素存储为字典键,其计数存储为字典值)
importcollections
>>>A = collections.Counter([1, 1, 2, 2, 3, 3, 3, 3, 4, 5, 6, 7])
>>>A
Counter({3: 4, 1: 2, 2: 2, 4: 1, 5: 1, 6: 1, 7: 1})
>>>A.most_common(1)
[(3, 4)]
>>>A.most_common(3)
[(3, 4), (1, 2), (2, 2)]
▍46、默认字典结构(字典的子类,在访问不存在的键时检索默认值)
>>>importcollections
>>>m = collections.defaultdict(int)
>>>m['a']
0
>>>m = collections.defaultdict(str)
>>>m['a']
''
>>>m['b'] += 'a'
>>>m['b']
'a'
>>>m = collections.defaultdict(lambda: '[default value]')
>>>m['a']
'[default value]'
>>>m['b']
'[default value]'
>>>m = collections.defaultdict(list)
>>>m['a']
[]
▍47、有序的dict结构(保持有序字典的子类)
>>>fromcollections importOrderedDict
>>>d = OrderedDict.fromkeys('abcde')
>>>d.move_to_end('b')
>>>''.join(d.keys)
'acdeb'
>>>d.move_to_end('b', last=False)
>>>''.join(d.keys)
'bacde'
▍48、Deques结构(Deques是堆栈和队列的概括)
>>>importcollection
>>>Q = collections.deque
>>>Q.append(1)
>>>Q.appendleft(2)
>>>Q.extend([3, 4])
>>>Q.extendleft([5, 6])
>>>Q
deque([6, 5, 2, 1, 3, 4])
>>>Q.pop
4
>>>Q.popleft
6
>>>Q
deque([5, 2, 1, 3])
>>>Q.rotate(3)
>>>Q
deque([2, 1, 3, 5])
>>>Q.rotate(-3)
>>>Q
deque([5, 2, 1, 3])
>>>last_three = collections.deque(maxlen=3)
>>>fori inrange(4):
...last_three.append(i)
...print', '.join(str(x) forx inlast_three)
...
0
0, 1
0, 1, 2
1, 2, 3
2, 3, 4
▍49、命名元组结构(创建类元组的对象,这些对象的字段可通过属性查找访问,也可索引和迭代)
>>>importcollections
>>>Point = collections.namedtuple('Point', ['x', 'y'])
>>>p = Point(x=1.0, y=2.0)
>>>p
Point(x=1.0, y=2.0)
>>>p.x
1.0
>>>p.y
2.0
▍50、使用字典来存储Switch
>>>func_dict = {'sum': lambdax, y: x + y, 'subtract': lambdax, y: x - y}
>>>func_dict['sum'](9,3)
12
>>>func_dict['subtract'](9,3)
6
▍51、数据类结构
>>>fromdataclasses importdataclass
>>>@dataclass
>>>classDataClassCard:
>>>rank: str
>>>suit: str
>>>queen_of_hearts = DataClassCard('Q', 'Hearts')
>>>queen_of_hearts.rank
'Q'
>>>queen_of_hearts
DataClassCard(rank='Q', suit='Hearts')
>>>queen_of_hearts == DataClassCard('Q', 'Hearts')
True
其他技巧
▍52、生成uuid
# This creates a randomized
#128-bit number that will almost certainly be unique.
# In fact, there are over 2¹²² possible
#UUIDs that can be generated.
#That’s over five undecillion (or 5,000,000,000,000,000,000,000,000,000,000,000,000).
>>>importuuid
>>>user_id = uuid.uuid4
>>>user_id
UUID('7c2faedd-805a-478e-bd6a-7b26210425c7')
▍53、使用LRU缓存进行记忆
importfunctools
@functools.lru_cache(maxsize=128)
deffibonacci(n):
ifn == 0:
return0
elifn == 1:
return1
returnfibonacci(n - 1) + fibonacci(n - 2)
▍54、Suppression of expressions
>>>fromcontextlib importsuppress
>>>withcontextlib.suppress(ZeroDivisi):
>>>10/0
# No exception raised
▍55、在需要设置和拆卸时创建上下文管理
地址:
https://docs.python.org/2/library/contextlib.html?source=post_page---------------------------
▍56、一种处理文件路径的优雅方法(3.4≥)
>>>frompathlib importPath
>>>data_folder = Path("source_data/text_files/)
# Path calculation and metadata
>>> file_to_open = data_folder / "raw_data.txt"
>>> file_to_open.name
"raw_data.txt"
>>> file_to_open.suffix
"txt"
>>>file_to_open.stem
"raw_data"
# Files functions
>>> f = open(file_to_open)
>>> f.read
# content of the file
>>> file_to_open.exists
True
▍57、将标准操作符实现为类的函数
地址:
https://docs.python.org/3/library/operator.html?source=post_page---------------------------
▍58、创建装饰器来分离concerns
>>>fromfunctools importwraps
>>>defadd_sandwich(wrapped):
>>>@wraps(wrapped)
>>>defwrapper(*args, **kwargs):
>>>returnwrapped(*args, **kwargs) + ' sandwich'
>>>returnwrapper
>>>@add_sandwich
>>>defham:
>>>return'ham'
>>>ham
'ham sandwich'
▍59、使用yield创建一个简单的迭代器
>>>deffoo(lst):
>>>forx inlst:
>>>yieldx
>>>yieldx*2
>>>a = [1, 3]
>>>list(foo(a))
[1, 2, 3, 6]
▍60、yield from use cases and tricks
地址:
https://stackoverflow.com/questions/9708902/in-practice-what-are-the-main-uses-for-the-new-yield-from-syntax-in-python-3?source=post_page---------------------------
彩蛋
▍61、Anti-gravity
importantigravity
antigravity.fly
▍62、The Zen of Python
>>>importthis
The Zen of Python, by Tim Peters
Beautiful isbetter than ugly.
Explicit isbetter than implicit.
Simple isbetter than complex.
Complex isbetter than complicated.
Flat isbetter than nested.
Sparse isbetter than dense.
Readability counts.
Special cases aren notspecial enough to breakthe rules.
Although practicality beats purity.
Errors should never passsilently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one andpreferably only one obvious way to do it.
Although that way may notbe obvious at first unless you are Dutch.
Now isbetter than never.
Although never isoften better than *right* now.
If the implementation ishard to explain, it isa bad idea.
If the implementation iseasy to explain, it may be a good idea.
Namespaces are one honking great idea let us do more of those!
希望以上62个小贴士对你在今天的学习和工作中有所帮助哦!
◆
◆
60+技术大咖与你相约 2019 AI ProCon!大会早鸟票已售罄,优惠票速抢进行中......2019 AI开发者大会将于9月6日-7日在北京举行,这一届AI开发者大会有哪些亮点?一线公司的大牛们都在关注什么?AI行业的风向是什么?2019 AI开发者大会,倾听大牛分享,聚焦技术实践,和万千开发者共成长。返回搜狐,查看更多
责任编辑: