收藏级:优雅编写Python3的66个小贴士!

论坛 期权论坛 期权     
量化投资与机器学习   2019-7-21 15:19   3881   0


标星★公众号     爱你们
作者:Eyal Trabelsi
编译:1+1=6 | 公众号翻译部
近期原创文章:
[h1] 5种机器学习算法在预测股价的应用(代码+数据)[/h1][h1] Two Sigma用新闻来预测股价走势,带你吊打Kaggle[/h1][h1] 2万字干货:利用深度学习最新前沿预测股价走势[/h1][h1] 机器学习在量化金融领域的误用![/h1][h1] 基于RNN和LSTM的股市预测方法[/h1][h1] 如何鉴别那些用深度学习预测股价的花哨模型?[/h1][h1] 优化强化学习Q-learning算法进行股市[/h1][h1] WorldQuant 101 Alpha、国泰君安 191 Alpha[/h1][h1] 基于回声状态网络预测股票价格(附代码)[/h1][h1] 计量经济学应用投资失败的7个原因[/h1][h1] 配对交易千千万,强化学习最NB!(文档+代码)[/h1][h1] 关于高盛在Github开源背后的真相![/h1][h1] 新一代量化带货王诞生!Oh My God![/h1][h1] 独家!关于定量/交易求职分享(附真实试题)[/h1][h1] Quant们的身份危机![/h1][h1] 拿起Python,防御特朗普的Twitter[/h1][h1] AQR最新研究 | 机器能“学习”金融吗?[/h1]



前言
今天公众号为大家带来一篇有关Python技巧的文章,可以帮助你编写优雅的Python3代码!

iterable技巧
▍1、创建一个数字序列(从0到10,间隔为2)
  1. >>> range(0,10,2)
  2. [0, 2, 4, 6, 8]
复制代码
▍2、对一串数字求和(从0到10,间隔为2
  1. >>> l = range(0,10,2)
  2. >>> sum(l)
  3. 20
复制代码
▍3、检查序列中的任一元素是否为True
  1. >>> any(a % 2 for a in range(0,10,2))
  2. True
复制代码
▍4、检查序列中的所有元素是否为True
  1. >>> all(a % 2 for a in range(0,10,2))
  2. True
复制代码
▍5、累计求和一串数字序列
  1. >>> import numpy as np
  2. >>> res = list(np.cumsum(range(0,10,2)))
  3. >>> res
  4. [ 0, 2, 6, 12, 20]
复制代码
6、给定每个iterable,通过添加索引来构造一个元组
  1. >>> a = ['Hello', 'world', '!']
  2. >>> list(enumerate(a))
  3. [(0, 'Hello'), (1, 'world'), (2, '!')]
复制代码
7、将iterable连接到单个字符串
  1. >>> a = ["python","really", "rocks"]
  2. >>> " ".join(a)
  3. 'python really rocks'
复制代码

▍8、组合两个可迭代的元组或pivot嵌套的iterables
  1. # Combining two iterables
  2. >>> a = [1, 2, 3]
  3. >>> b = ['a', 'b', 'c']
  4. >>> z = zip(a, b)
  5. >>> z
  6. [(1, 'a'), (2, 'b'), (3, 'c')]
  7. # Pivoting list of tuples
  8. >>> zip(*z)
  9. [(1, 2, 3), ('a', 'b', 'c')]
复制代码
▍9、从iterables中获取最小值/最大值(具有/不具有特定功能)
  1. # Getting maximum from iterable
  2. >>> a = [1, 2, -3]
  3. >>> max(a)
  4. 2
  5. # Getting maximum from iterable
  6. >>> min(a)
  7. 1
  8. # Bot min/max has key value to allow to get maximum by appliing function
  9. >>> max(a,key=abs)
  10. 3
复制代码
▍10、可迭代排序(可以通过“compare”函数排序)
  1. >>> a = [1, 2, -3]
  2. >>> sorted(a)
  3. [-3, 1, 2]
  4. >>> sorted(a,key=abs)
  5. [1, 2, -3]
复制代码
▍11、将单个字符串拆分为列表
  1. >>> s = "a,b,c"
  2. >>> s.split(",")
  3. ["a", "b", "c"]
复制代码
▍12、初始化一个包含重复数字的列表
  1. >> [1]* 10
  2. [1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
复制代码
▍13、合并/插入两个字典
  1. >>> a = {"a":1, "b":1}
  2. >>> b = {"b":2, "c":1}
  3. >>> a.update(b)
  4. >>> a
  5. {"a":1, "b":2, "c":1}
复制代码
▍14、命名和保存iterables切片
  1. # Naming slices (slice(start, end, step))
  2. >>> a = [0, 1, 2, 3, 4, 5]
  3. >>> LASTTHREE = slice(-3, None)
  4. >>> LASTTHREE
  5. slice(-3, None, None)
  6. >>> a[LASTTHREE]
  7. [3, 4, 5]
复制代码
▍15、在列表中查找项的索引
  1. >>> a = ["foo", "bar", "baz"]
  2. >>> a.index("bar")
  3. 1
复制代码
▍16、在iterables中查找最小/最大项的索引
  1. >>> a = [2, 3, 1]
  2. >>> min(enumerate(a),key=lambda x: x[1])[0]
  3. 2
复制代码
▍17、旋转iterables的k个元素
  1. >>> a = [1, 2, 3, 4]
  2. >>> k = 2
  3. >>> a[-2:] + a[:-2]
  4. [3, 4, 1, 2]
复制代码
▍18、删除字符串末尾/开始/两端无用的字符
  1. >>> name = "//George//"
  2. >>> name.strip("/")
  3. 'George'
  4. >>> name.rstrip("/")
  5. '//George'
  6. >>> name.lstrip("/")
  7. 'George//'
复制代码
▍19、倒序iterables的顺序(字符串、列表等)
  1. # Reversing string
  2. >>> s = "abc"
  3. >>> s[::-1]
  4. "cba"
  5. # Reversing list
  6. >>> l = ["a", "b", "c"]
  7. >>> l[::-1]
  8. ["c", "b", "a"]
复制代码
branching技巧
▍20、多个short-cut
  1. >>> n = 10
  2. >>> 1 < n < 20
  3. True
复制代码
▍21、For-else结构在搜索某些东西并找到它时很有用
  1. for i in mylist:
  2.      if i == theflag:
  3.          break
  4.      process(i)
  5. else:
  6.      raise ValueError("List argument missing terminal flag.")
复制代码
▍22、Trenary operator
  1. >>> "Python ROCK" if True else " I AM GRUMPY"
  2. "Python ROCK"
复制代码
▍23、Try-catch-else结构
  1. try:
  2.      foo()
  3. except Exception:
  4.      print("Exception occured")
  5. else:
  6.      print("Exception didnt occur")
  7. finally:
  8.      print("Always gets here")
复制代码
▍24、While-else结构
  1. i = 5
  2. while i > 1:
  3.      print("Whil-ing away!")
  4.      i -= 1
  5.      if i == 3:
  6.          break
  7. else:
  8.     print("Finished up!")
复制代码
comprehensions(推导式)技巧
▍25、List推导式
  1. >>> m = [x ** 2 for x in range(5)]
  2. >>> m
  3. [0, 1, 4, 9, 16]
复制代码
▍26、Set推导式
  1. >>> m = {x ** 2 for x in range(5)}
  2. >>> m
  3. {0, 1, 4, 9, 16}
复制代码
▍27、Dict推导式
  1. >>> m = {x: x ** 2 for x in range(5)}
  2. >>> m
  3. {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}
复制代码
▍28、Generator推导式
  1. # A generator comprehension is the lazy version of a list comprehension.
  2. >>> m = (x ** 2 for x in range(5))
  3. >>> m
  4. >>> list(m)
  5. [0, 1, 4, 9, 16]
  6. >>> m = (x ** 2 for x in range(5))
  7. >>> next(m)
  8. 0
  9. >>> list(m)
  10. [1, 4, 9, 16]
复制代码
▍29、list推导使用当前值和过往值
  1. >>> a = [1, 2, 4,2]
  2. >>> [y - x for x,y in zip(a,a[1:])]
  3. [1, 2, -2]
复制代码
unpacking技巧
▍30、从iterable解压缩变量
  1. # One can unpack all iterables (tuples, list etc)
  2. >>> a, b, c = 1, 2, 3
  3. >>> a, b, c
  4. (1, 2, 3)
  5. >>> a, b, c = [1, 2, 3]
  6. >>> a, b, c
  7. (1, 2, 3)
复制代码
▍31、交换变量值
  1. >>> a, b = 1, 2
  2. >>> a, b = b, a
  3. >>> a, b
  4. (2, 1)
复制代码
▍32、在不指示所有元素的情况下从iterable解包变量
  1. >>> a, *b, c = [1, 2, 3, 4, 5]
  2. >>> a
  3. 1
  4. >>> b
  5. [2, 3, 4]
  6. >>> c
  7. 5
复制代码
▍33、使用splat运算符解包变量
  1. >>> def test(x, y, z):
  2. >>>      print(x, y, z)
  3. >>> res = test(*[10, 20, 30])
  4. 10 20 30
  5. >>> res = test(**{'x': 1, 'y': 2, 'z': 3} )
  6. 10 20 30
  7. view raw
复制代码
Itertools技巧
▍34、Flatten iterables
  1. >>> a = [[1, 2], [3, 4], [5, 6]]
  2. >>> list(itertools.chain.from_iterable(a))
  3. [1, 2, 3, 4, 5, 6]
复制代码
▍35、从iterables创建笛卡尔积
  1. >>> for p in itertools.product([1, 2, 3], [4, 5]):
  2. >>>      print(''.join(str(x) for x in p))
  3. (1, 4)
  4. (1, 5)
  5. (2, 4)
  6. (2, 5)
  7. (3, 4)
  8. (3, 5)
复制代码
▍36、从iterable创建排列
  1. >>> for p in itertools.permutations([1, 2, 3, 4]):
  2. >>>      print(''.join(str(x) for x in p))
  3. 123
  4. 132
  5. 213
  6. 231
  7. 312
  8. 321
复制代码
▍37、从iterable创建ngram
  1. >>> from itertools import islice
  2. >>> def n_grams(a, n):
  3. ...          z = (islice(a, i, None) for i in range(n))
  4. ...          return zip(*z)
  5. ...
  6. >>> a = [1, 2, 3, 4, 5, 6]
  7. >>> n_grams(a, 3)
  8. [(1, 2, 3), (2, 3, 4), (3, 4, 5), (4, 5, 6)]
  9. >>> n_grams(a, 2)
  10. [(1, 2), (2, 3), (3, 4), (4, 5), (5, 6)]
  11. >>> n_grams(a, 4)
  12. [(1, 2, 3, 4), (2, 3, 4, 5), (3, 4, 5, 6)]
复制代码
▍38、使用填充组合元组的两个迭代器或使用填充pivot嵌套迭代
  1. >>> import itertools as it
  2. >>> x = [1, 2, 3, 4, 5]
  3. >>> y = ['a', 'b', 'c']
  4. >>> list(zip(x, y))
  5. [(1, 'a'), (2, 'b'), (3, 'c')]
  6. >>> list(it.zip_longest(x, y))
  7. [(1, 'a'), (2, 'b'), (3, 'c'), (4, None), (5, None)]
复制代码
▍39、从一个iterable n中创建k个组合
  1. >>> import itertools
  2. >>> bills = [20, 20, 20, 10, 10, 10, 10, 10, 5, 5, 1, 1, 1, 1, 1]
  3. >>> list(itertools.combinations(bills, 3))
  4. [(20, 20, 20), (20, 20, 10), (20, 20, 10), ... ]
复制代码
▍40、在给定函数情况下创建一个迭代的累积结果
  1. >>> import itertools
  2. >>> list(itertools.accumulate([9, 21, 17, 5, 11, 12, 2, 6], min))
  3. [9, 9, 9, 5, 5, 5, 2, 2]
复制代码
▍41、创建一个迭代器,只要谓词为True,就从iterable返回元素
  1. >>> import itertools
  2. >>> itertools.takewhile(lambda x: x < 3, [0, 1, 2, 3, 4])
  3. [0, 1, 2]
  4. >>> it.dropwhile(lambda x: x < 3, [0, 1, 2, 3, 4])
  5. [3, 4]
复制代码
▍42、创建一个迭代器,它从iterable中过滤元素,只返回谓词为False的元素
  1. >>> import itertools
  2. # keeping only false values
  3. >>> list(itertools.filterfalse(bool, [None, False, 1, 0, 10]))
  4. [None, False, 0]
复制代码
▍43、创建一个迭代器,使用从迭代的迭代中获得的参数来计算函数
  1. >>> import itertools
  2. >>> import operator
  3. >>> a = [(2, 6), (8, 4), (7, 3)]
  4. >>> list(itertools.starmap(operator.mul, a))
  5. [12, 32, 21]
复制代码

collections技巧▍44、设置基本操作
  1. >>> A = {1, 2, 3, 3}
  2. >>> A
  3. set([1, 2, 3])
  4. >>> B = {3, 4, 5, 6, 7}
  5. >>> B
  6. set([3, 4, 5, 6, 7])
  7. >>> A | B
  8. set([1, 2, 3, 4, 5, 6, 7])
  9. >>> A & B
  10. set([3])
  11. >>> A - B
  12. set([1, 2])
  13. >>> B - A
  14. set([4, 5, 6, 7])
  15. >>> A ^ B
  16. set([1, 2, 4, 5, 6, 7])
  17. >>> (A ^ B) == ((A - B) | (B - A))
  18. True
复制代码
▍45、计数器数据结构(无序集合,其中元素存储为字典键,其计数存储为字典值)
  1. import collections
  2. >>> A = collections.Counter([1, 1, 2, 2, 3, 3, 3, 3, 4, 5, 6, 7])
  3. >>> A
  4. Counter({3: 4, 1: 2, 2: 2, 4: 1, 5: 1, 6: 1, 7: 1})
  5. >>> A.most_common(1)
  6. [(3, 4)]
  7. >>> A.most_common(3)
  8. [(3, 4), (1, 2), (2, 2)]
复制代码
▍46、默认字典结构(字典的子类,在访问不存在的键时检索默认值)
  1. >>> import collections
  2. >>> m = collections.defaultdict(int)
  3. >>> m['a']
  4. 0
  5. >>> m = collections.defaultdict(str)
  6. >>> m['a']
  7. ''
  8. >>> m['b'] += 'a'
  9. >>> m['b']
  10. 'a'
  11. >>> m = collections.defaultdict(lambda: '[default value]')
  12. >>> m['a']
  13. '[default value]'
  14. >>> m['b']
  15. '[default value]'
  16. >>> m = collections.defaultdict(list)
  17. >>> m['a']
  18. []
复制代码

▍47、有序的dict结构(保持有序字典的子类)
  1. >>> from collections import OrderedDict
  2. >>> d = OrderedDict.fromkeys('abcde')
  3. >>> d.move_to_end('b')
  4. >>> ''.join(d.keys())
  5. 'acdeb'
  6. >>> d.move_to_end('b', last=False)
  7. >>> ''.join(d.keys())
  8. 'bacde'
复制代码
▍48、Deques结构(Deques是堆栈和队列的概括)
  1. >>> import collection
  2. >>> Q = collections.deque()
  3. >>> Q.append(1)
  4. >>> Q.appendleft(2)
  5. >>> Q.extend([3, 4])
  6. >>> Q.extendleft([5, 6])
  7. >>> Q
  8. deque([6, 5, 2, 1, 3, 4])
  9. >>> Q.pop()
  10. 4
  11. >>> Q.popleft()
  12. 6
  13. >>> Q
  14. deque([5, 2, 1, 3])
  15. >>> Q.rotate(3)
  16. >>> Q
  17. deque([2, 1, 3, 5])
  18. >>> Q.rotate(-3)
  19. >>> Q
  20. deque([5, 2, 1, 3])
  21. >>> last_three = collections.deque(maxlen=3)
  22. >>> for i in range(4):
  23. ...         last_three.append(i)
  24. ...         print ', '.join(str(x) for x in last_three)
  25. ...
  26. 0
  27. 0, 1
  28. 0, 1, 2
  29. 1, 2, 3
  30. 2, 3, 4
复制代码
▍49、命名元组结构(创建类元组的对象,这些对象的字段可通过属性查找访问,也可索引和迭代)
  1. >>> import collections
  2. >>> Point = collections.namedtuple('Point', ['x', 'y'])
  3. >>> p = Point(x=1.0, y=2.0)
  4. >>> p
  5. Point(x=1.0, y=2.0)
  6. >>> p.x
  7. 1.0
  8. >>> p.y
  9. 2.0
复制代码
▍50、使用字典来存储Switch
  1. >>> func_dict = {'sum': lambda x, y: x + y, 'subtract': lambda x, y: x-y}
  2. >>> func_dict['sum'](9,3)
  3. 12
  4. >>> func_dict['subtract'](9,3)
  5. 6
复制代码

▍51、数据类结构
  1. >>> from dataclasses import dataclass
  2. >>> @dataclass
  3. >>> class DataClassCard:
  4. >>>      rank: str
  5. >>>      suit: str
  6. >>> queen_of_hearts = DataClassCard('Q', 'Hearts')
  7. >>> queen_of_hearts.rank
  8. 'Q'
  9. >>> queen_of_hearts
  10. DataClassCard(rank='Q', suit='Hearts')
  11. >>> queen_of_hearts == DataClassCard('Q', 'Hearts')
  12. True
复制代码

其他技巧▍52、生成uuid
  1. # This creates a randomized
  2. #128-bit number that will almost certainly be unique.
  3. # In fact, there are over 2 possible
  4. #UUIDs that can be generated.
  5. #That’s over five undecillion (or 5,000,000,000,000,000,000,000,000,000,000,000,000).
  6. >>> import uuid
  7. >>> user_id = uuid.uuid4()
  8. >>> user_id
  9. UUID('7c2faedd-805a-478e-bd6a-7b26210425c7')
复制代码
▍53、使用LRU缓存进行记忆
  1. import functools
  2. @functools.lru_cache(maxsize=128)
  3. def fibonacci(n):
  4.      if n == 0:
  5.          return 0
  6.      elif n == 1:
  7.          return 1
  8.      return fibonacci(n - 1) + fibonacci(n - 2)
复制代码
▍54、Suppression of expressions
  1. >>> from contextlib import suppress
  2. >>> with contextlib.suppress(ZeroDivisionError):
  3. >>>  10/0
  4. # No exception raised
复制代码

▍55、在需要设置和拆卸时创建上下文管理



地址:
https://docs.python.org/2/library/contextlib.html?source=post_page---------------------------

▍56、一种处理文件路径的优雅方法(3.4≥)
  1. >>> from pathlib import Path
  2. >>> data_folder = Path("source_data/text_files/)
  3. # Path calculation and metadata
  4. >>> file_to_open = data_folder / "raw_data.txt"
  5. >>> file_to_open.name
  6. "raw_data.txt"
  7. >>> file_to_open.suffix
  8. "txt"
  9. >>>file_to_open.stem
  10. "raw_data"
  11. # Files functions
  12. >>> f = open(file_to_open)
  13. >>> f.read()
  14. # content of the file
  15. >>> file_to_open.exists()
  16. True
复制代码

▍57、将标准操作符实现为类的函数



地址:
https://docs.python.org/3/library/operator.html?source=post_page---------------------------

▍58、创建装饰器来分离concerns
  1. >>>from functools import wraps
  2. >>>def add_sandwich(wrapped):
  3. >>>      @wraps(wrapped)
  4. >>>      def wrapper(*args, **kwargs):
  5. >>>            return wrapped(*args, **kwargs) + ' sandwich'
  6. >>>      return wrapper
  7. >>>@add_sandwich
  8. >>>def ham():
  9. >>>     return 'ham'
  10. >>>ham()
  11. 'ham sandwich'
复制代码
▍59、使用yield创建一个简单的迭代器
  1. >>> def foo(lst):
  2. >>>      for x in lst:
  3. >>>          yield x
  4. >>>          yield x*2
  5. >>> a = [1, 3]
  6. >>> list(foo(a))
  7. [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
  1. import antigravity
  2. antigravity.fly()
复制代码
▍62、The Zen of Python
  1. >>> import this
  2. The Zen of Python, by Tim Peters
  3. Beautiful is better than ugly.
  4. Explicit is better than implicit.
  5. Simple is better than complex.
  6. Complex is better than complicated.
  7. Flat is better than nested.
  8. Sparse is better than dense.
  9. Readability counts.
  10. Special cases aren not special enough to break the rules.
  11. Although practicality beats purity.
  12. Errors should never pass silently.
  13. Unless explicitly silenced.
  14. In the face of ambiguity, refuse the temptation to guess.
  15. There should be one and preferably only one obvious way to do it.
  16. Although that way may not be obvious at first unless you are Dutch.
  17. Now is better than never.
  18. Although never is often better than *right* now.
  19. If the implementation is hard to explain, it is a bad idea.
  20. If the implementation is easy to explain, it may be a good idea.
  21. Namespaces are one honking great idea let us do more of those!
复制代码
▍63、另一种很酷彩蛋



地址:
https://github.com/OrkoHunter/python-easter-eggs?source=post_page--------------------------

理解context的技巧▍64、使用_main_ .py文件显式标记入口点



地址:
https://shaneoneill.io/2019/06/12/use-__main__-py/?source=post_page---------------------------

▍65、对象属性列表
  1. >>> dir()
  2. ['__annotations__', '__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__']
  3. >>> dir("Hello World")
  4. ['__add__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'capitalize', 'casefold', 'center', 'count', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'format_map', 'index', 'isalnum', 'isalpha', 'isascii', 'isdecimal', 'isdigit', 'isidentifier', 'islower', 'isnumeric', 'isprintable', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'maketrans', 'partition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill']
复制代码
▍66、关于活动对象的附加信息



地址:
https://docs.python.org/3/library/inspect.html?source=post_page---------------------------

希望以上66个小贴士对你在今天的学习和工作中有所帮助哦!




—End—

量化投资与机器学习微信公众号,是业内垂直于QuantMFECST、AI等专业的流量化自媒体。公众号拥有来自公募、私募、券商、银行、海外等众多圈内10W+关注者。每日发布行业前沿研究成果和最新量化资讯。

分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:55
帖子:13
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP