标星★公众号 爱你们
作者: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)
- >>> 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 % 2 for a in range(0,10,2))
- True
复制代码 ▍4、检查序列中的所有元素是否为True
- >>> all(a % 2 for a in range(0,10,2))
- True
复制代码 ▍5、累计求和一串数字序列
- >>> import numpy as np
- >>> 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=lambda x: 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结构在搜索某些东西并找到它时很有用
- for i in mylist:
- if i == theflag:
- break
- process(i)
- else:
- raise ValueError("List argument missing terminal flag.")
复制代码 ▍22、Trenary operator
- >>> "Python ROCK" if True else " I AM GRUMPY"
- "Python ROCK"
复制代码 ▍23、Try-catch-else结构
- try:
- foo()
- except Exception:
- print("Exception occured")
- else:
- print("Exception didnt occur")
- finally:
- print("Always gets here")
复制代码 ▍24、While-else结构
- i = 5
- while i > 1:
- print("Whil-ing away!")
- i -= 1
- if i == 3:
- break
- else:
- print("Finished up!")
复制代码 comprehensions(推导式)技巧
▍25、List推导式
- >>> m = [x ** 2 for x in range(5)]
- >>> m
- [0, 1, 4, 9, 16]
复制代码 ▍26、Set推导式
- >>> m = {x ** 2 for x in range(5)}
- >>> m
- {0, 1, 4, 9, 16}
复制代码 ▍27、Dict推导式
- >>> m = {x: x ** 2 for x in range(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 ** 2 for x in range(5))
- >>> m
- >>> list(m)
- [0, 1, 4, 9, 16]
- >>> m = (x ** 2 for x in range(5))
- >>> next(m)
- 0
- >>> list(m)
- [1, 4, 9, 16]
复制代码 ▍29、list推导使用当前值和过往值
- >>> a = [1, 2, 4,2]
- >>> [y - x for x,y in zip(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运算符解包变量
- >>> def test(x, y, z):
- >>> print(x, y, z)
- >>> res = test(*[10, 20, 30])
- 10 20 30
- >>> res = test(**{'x': 1, 'y': 2, 'z': 3} )
- 10 20 30
- 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创建笛卡尔积
- >>> for p in itertools.product([1, 2, 3], [4, 5]):
- >>> print(''.join(str(x) for x in p))
- (1, 4)
- (1, 5)
- (2, 4)
- (2, 5)
- (3, 4)
- (3, 5)
复制代码 ▍36、从iterable创建排列
- >>> for p in itertools.permutations([1, 2, 3, 4]):
- >>> print(''.join(str(x) for x in p))
- 123
- 132
- 213
- 231
- 312
- 321
复制代码 ▍37、从iterable创建ngram
- >>> from itertools import islice
- >>> def n_grams(a, n):
- ... z = (islice(a, i, None) for i in range(n))
- ... return zip(*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嵌套迭代
- >>> import itertools as it
- >>> 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个组合
- >>> import itertools
- >>> 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、在给定函数情况下创建一个迭代的累积结果
- >>> import itertools
- >>> list(itertools.accumulate([9, 21, 17, 5, 11, 12, 2, 6], min))
- [9, 9, 9, 5, 5, 5, 2, 2]
复制代码 ▍41、创建一个迭代器,只要谓词为True,就从iterable返回元素
- >>> import itertools
- >>> itertools.takewhile(lambda x: x < 3, [0, 1, 2, 3, 4])
- [0, 1, 2]
- >>> it.dropwhile(lambda x: x < 3, [0, 1, 2, 3, 4])
- [3, 4]
复制代码 ▍42、创建一个迭代器,它从iterable中过滤元素,只返回谓词为False的元素
- >>> import itertools
- # keeping only false values
- >>> list(itertools.filterfalse(bool, [None, False, 1, 0, 10]))
- [None, False, 0]
复制代码 ▍43、创建一个迭代器,使用从迭代的迭代中获得的参数来计算函数
- >>> import itertools
- >>> import operator
- >>> 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、计数器数据结构(无序集合,其中元素存储为字典键,其计数存储为字典值)
- import collections
- >>> 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、默认字典结构(字典的子类,在访问不存在的键时检索默认值)
- >>> import collections
- >>> 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结构(保持有序字典的子类)
- >>> from collections import OrderedDict
- >>> 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是堆栈和队列的概括)
- >>> import collection
- >>> 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)
- >>> for i in range(4):
- ... last_three.append(i)
- ... print ', '.join(str(x) for x in last_three)
- ...
- 0
- 0, 1
- 0, 1, 2
- 1, 2, 3
- 2, 3, 4
复制代码 ▍49、命名元组结构(创建类元组的对象,这些对象的字段可通过属性查找访问,也可索引和迭代)
- >>> import collections
- >>> 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': lambda x, y: x + y, 'subtract': lambda x, y: x-y}
- >>> func_dict['sum'](9,3)
- 12
- >>> func_dict['subtract'](9,3)
- 6
复制代码
▍51、数据类结构
- >>> from dataclasses import dataclass
- >>> @dataclass
- >>> class DataClassCard:
- >>> 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).
- >>> import uuid
- >>> user_id = uuid.uuid4()
- >>> user_id
- UUID('7c2faedd-805a-478e-bd6a-7b26210425c7')
复制代码 ▍53、使用LRU缓存进行记忆
- import functools
- @functools.lru_cache(maxsize=128)
- def fibonacci(n):
- if n == 0:
- return 0
- elif n == 1:
- return 1
- return fibonacci(n - 1) + fibonacci(n - 2)
复制代码 ▍54、Suppression of expressions
- >>> from contextlib import suppress
- >>> with contextlib.suppress(ZeroDivisionError):
- >>> 10/0
- # No exception raised
复制代码
▍55、在需要设置和拆卸时创建上下文管理
地址:
https://docs.python.org/2/library/contextlib.html?source=post_page---------------------------
▍56、一种处理文件路径的优雅方法(3.4≥)
- >>> from pathlib import Path
- >>> 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
- >>>from functools import wraps
- >>>def add_sandwich(wrapped):
- >>> @wraps(wrapped)
- >>> def wrapper(*args, **kwargs):
- >>> return wrapped(*args, **kwargs) + ' sandwich'
- >>> return wrapper
- >>>@add_sandwich
- >>>def ham():
- >>> return 'ham'
- >>>ham()
- 'ham sandwich'
复制代码 ▍59、使用yield创建一个简单的迭代器
- >>> def foo(lst):
- >>> for x in lst:
- >>> yield x
- >>> yield x*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
- import antigravity
- antigravity.fly()
复制代码 ▍62、The Zen of Python
- >>> import this
- The Zen of Python, by Tim Peters
- Beautiful is better than ugly.
- Explicit is better than implicit.
- Simple is better than complex.
- Complex is better than complicated.
- Flat is better than nested.
- Sparse is better than dense.
- Readability counts.
- Special cases aren not special enough to break the rules.
- Although practicality beats purity.
- Errors should never pass silently.
- Unless explicitly silenced.
- In the face of ambiguity, refuse the temptation to guess.
- There should be one and preferably only one obvious way to do it.
- Although that way may not be obvious at first unless you are Dutch.
- Now is better than never.
- Although never is often better than *right* now.
- If the implementation is hard to explain, it is a bad idea.
- If the implementation is easy to explain, it may be a good idea.
- 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、对象属性列表
- >>> dir()
- ['__annotations__', '__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__']
- >>> dir("Hello World")
- ['__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—
量化投资与机器学习微信公众号,是业内垂直于Quant、MFE、CST、AI等专业的主流量化自媒体。公众号拥有来自公募、私募、券商、银行、海外等众多圈内10W+关注者。每日发布行业前沿研究成果和最新量化资讯。
|
|