目录
一、(浅shallow)拷贝(copy)和深拷贝(deep copy)的区别:
# Python
>>> from copy import copy, deepcopy
>>> ll = [[1, 2], [3, 4]]
>>> ll2 = copy(ll)
>>> ll3 = deepcopy(ll)
>>> ll[0][0] = 10
>>> ll
[[10, 2], [3, 4]]
>>> ll2
[[10, 2], [3, 4]]
>>> ll3
[[1, 2], [3, 4]]
注:需要先安装
deepcopy
,语句from copy import copy, deepcopy
才不会报错。
# Python
>>> pip install deepcopy
一、difflib.get_close_matches
- 模糊匹配的朋友:
Python中的difflib.get_close_matches
模块你用来对字符串进行模糊匹配处理的朋友,比如当用户拼写错误时,我们想要建议一个紧密匹配的名称。这是一个内置的库,不需要安装:
# Python
>>> import difflib
>>> from difflib import get_close_matches
>>> names = ("tim", "sara", "nancy", "henrik")
>>> get_close_matches("fancy", names)
['nancy']
>>> get_close_matches("zara", names)
['sara']
>>> get_close_matches("henrico", names)
['henrik']
getattr
方法
Python中的getattr
方法一定会让您大吃一惊,请记住这一点(来自文档):
“如果指定的属性不存在,就返回默认值(如果有的话),否则就会引发AttributeErro
r的例外信息”:
# Python
>>> class Foo:
... bar = 1
...
>>> f = Foo()
>>> getattr(f, "bar")
1
>>> getattr(f, "bar2")
Traceback (most recent call last):
File "", line 1, in
AttributeError: 'Foo' object has no attribute 'bar2'
>>> getattr(f, "bar2", 2)
2
获取当前工作日
在Python中如何知道当天是星期几?
# Python
>>> from datetime import datetime
>>> datetime.now()
datetime.datetime(2021, 5, 27, 10, 46, 27, 161788)
>>> datetime.now().strftime("%A")
'Thursday'
>>> datetime.now().strftime("%a")
'Thu'
使用splitlines()
函数拆分文本
如果您使用的是Windows或(旧)Apple计算机(它们分别是用\ r\n
和\r
来进行换行的),那么使用Python的split("\n")
函数将文本拆分为行,就有可能会返回很奇怪的结果。
在这
在这种情况下,使用splitlines()
就是一个更安全的选择:
# Python
>>> "first line\r\nsecond line".split("\n")
['first line\r', 'second line']
>>> "first line\r\nsecond line".splitlines()
['first line', 'second line']
>>> "first line\rsecond line".splitlines()
['first line', 'second line']
>>> "first line\nsecond line".splitlines()
['first line', 'second line']
用dict
推导式反转字典的键和值
使用dict推导式来反转Python的键和值
# Python
>>> belts = {10: "white", 50: "yellow", 100: "orange", 175: "green", 250: "blue"}
>>> {belt: score for score, belt in belts.items()}
{'white': 10, 'yellow': 50, 'orange': 100, 'green': 175, 'blue': 250}
timedelta
在其字符串表示形式中使用divmod
:
有趣的是,看看Pythontimedelta
是如何在其字符串表示形式中使用divmod
:
# Python
>>> def __str__(self):
... mm, ss = divmod(self._seconds, 60)
... hh, mm = divmod(mm, 60)
...
>>> from datetime import timedelta
>>> timedelta(seconds=4000)
>>> timedelta(seconds=4000)
datetime.timedelta(seconds=4000)
>>> print(str(timedelta(seconds=4000)))
1:06:40
从某条日志记录中提取datetime
如何使用Python从某条日志记录中提取datetime
(或者,您可以使用dateutil.parser.parse
,但这个模块不是标准库)
# Python
>>> line = "INFO 2014-07-03T23:27:51 supybot Shutdown complete"
>>> timestamp = line.split()[1]
>>> timestamp
'2014-07-03T23:27:51'
>>> from datetime import datetime
>>> datetime.strptime(timestamp, "%Y-%m-%dT%H:%M:%S")
datetime.datetime(2014, 7, 3, 23, 27, 51)
datetime
类的fromtimestamp
类方法
Python的datetime
类有一个fromtimestamp
类方法,可以从POSIX时间戳中创建datetime对象,例如:
# Python
>>> tstamp = time()
>>> tstamp
1622112421.3426158
>>> from datetime import datetime
>>> datetime.fromtimestamp(tstamp)
datetime.datetime(2021, 5, 27, 18, 47, 1, 342616)
>>>
解析博客供稿的一些常见类别
解析博客供稿的一些常见类别:
# Python
>>> import xml.etree.ElementTree as ET
>>> from collections import Counter
>>> import requests
>>> resp = requests.get("https://pybit.es/feeds/all.rss.xml")
>>> tree = ET.fromstring(resp.content)
>>> categories = (e.text for e in tree.findall("./channel/item/category"))
>>> Counter(categories).most_common(5)
[('learning', 102), ('news', 98), ('twitter', 96), ('python', 88), ('tips', 75)]
检查某个对象是否是内建的
这个Python对象是内置的吗?
# Python
>>> from inspect import isbuiltin
>>> def func():
... pass
...
>>> isbuiltin(func)
False
>>> isbuiltin(any)
True
>>> isbuiltin(sorted)
True
选择一个随机元素
从某个Python范围中选择一个随机元素:
# Python
>>> from random import randrange
>>> randrange(25, 51, 5)
40
>>> randrange(25, 51, 5)
25
>>> randrange(25, 51, 5)
50
>>> randrange(25, 51, 2)
43
collections.Counter
太神奇了!
collections.Counter
真的是太神奇了:
# Python
>>> from collections import Counter
>>> languages = "Python Jave Perl Python JS C++ JS Python".split()
>>> Counter(languages)
Counter({'Python': 3, 'JS': 2, 'Jave': 1, 'Perl': 1, 'C++': 1})
>>> Counter(languages).most_common(2)
[('Python', 3), ('JS', 2)]
__str__
和__repr__
的区别
Python中的__str__
和__repr__
有什么区别?
内德·巴切德尔(Ned Batchelder)说得好:“我的经验法则是:__repr__
是为开发人员设计的,而__str__
则是为客户开发的。(”https://stackoverflow.com/a/1438297)
# Python
>>> from datetime import date
>>> today = date.today()
>>> str(today)
'2021-05-28'
>>> repr(today)
删除所有前导空白
测试代码输出时一种有用的技术就是删除所有前导空白。
您可以为此使用inspect.cleandoc
或textwrap.dedent
,这是前者的一个示例:
# Pyhton
from inspect import cleandoc
def test_uesr_selects_tree_emoji(capfd):
actual = capfd.readouterr()[0].strip()
expected = cleandoc("""
1
2
3
4
5
""")
assert actual == expected
编码所使用的操作系统/系统
嗨,Python,我今天是在什么操作系统或系统上进行编码的?
# Python
>>> import platform
>>> platform.machine()
'AMD64'
>>> platform.node()
'VICTOR_2ND_LAPT'
>>> platform.system()
'Windows'
计算两个日期之间的天数
当自己开发的自动化工具能够对重要的日期进行提醒的时候,总是很有趣的。
比如,你能相信到今天我们已经存在1600多天了吗?
当然这需要通过Python来表达它:
# Python
>>> # 28th of May 2021
>>> from datetime import date
>>> date.today() - date(2016, 12, 19)
datetime.timedelta(days=1621)
从特定数字开始的计数器
如果在Python中您需要一个从特定数字开始的计数器,那么就可以使用itertools.count
:
# Python
>>> from itertools import count
>>> counter = count(1001)
>>> next(counter)
1001
>>> next(counter)
1002
>>> counter = count(1001, step=2)
>>> next(counter)
1001
>>> next(counter)
1003
理解非英语日期字符串:
使用Python的dateparser
(PyPI)理解非英语日期字符串:
# Python
>>> date = "5 de mayo de 2021"
>>> from dateparser import parse
>>> parse(date)
datetime.datetime(2021, 5, 5, 0, 0)
注:其中的
5 de mayo de 2021
为西班牙语。中文也可以识别:
# Python
>>> from dateparser import parse
>>> date = "2021年5月5日"
>>> parse(date)
datetime.datetime(2021, 5, 5, 0, 0)
>>> date = "2021年5月25日"
>>> parse(date)
datetime.datetime(2021, 5, 25, 0, 0)
注:需要预先安装
dateparser
库。
抓取某个博客中所有包含class
字样文章的标题:
使用requests
和Beautiful Soup
来抓取https://pybit.es/的博客,查找包含class
字样文章的标题:
# Python
>>> from pprint import pprint as pp
>>> import bs4
>>> import requests
>>> resp =requests.get("https://pybit.es/archives")
>>> soup = bs4.BeautifulSoup(resp.text, "html.parser")
>>> articles = [link["href"] for link in soup.find_all("a", href=True) if "class" in link.text.lower()]
>>> pp(articles)
['https://pybit.es/when-classes.html',
'https://pybit.es/codechallenge24_review.html',
'https://pybit.es/codechallenge24.html',
'https://pybit.es/python-subclasses.html',
'https://pybit.es/python-classes.html']
为namedtuple
添加类型提示
为namedtuple
添加类型提示:
# Python
>>> from typing import NamedTuple
>>> class Karma(NamedTuple):
... giver: str
... receiver: str
... score: int
...
# 如果输入如下的内容:
# Karma("bob", "julian", "5")
# Python回给出如下的错误信息:
# Argument 3 to "Karma" has incompatible type "str", expected "int"
# 但是下面这样就可以
????
>>> karma = Karma("bob", "julian", 5)
>>> karma
Karma(giver='bob', receiver='julian', score=5)
使用re
模块中的findall
查找与正则表达式模式匹配的所有实例
使用re
模块中的findall
查找与正则表达式模式匹配的所有实例:
# Python
>>> tweet = "We love tweeting #Python #tips because it's a beautful #programming language"
>>> import re
>>> re.findall(r"#(\w+)", tweet)
['Python', 'tips', 'programming']
检查字符串中的所有字符是否都是数字
使用Python中的str.isdigit()
方法检查字符串中的所有字符是否都是数字:
# Python
>>> "a".isdigit()
False
>>> "w2".isdigit()
False
>>> "1".isdigit()
True
>>> "690".isdigit()
True
>>> str.isdigit("1")
True
获取所有月份的名称
可以使用Python的calender
模块获取所有月份的名称:
# Python
>>> import calendar
>>> months = calendar.month_abbr[1:]
>>> months
['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
>>> months = calendar.month_abbr[:]
>>> months
['', 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
>>>
>>> months = calendar.month_abbr[1:]
>>>
>>> months_nums_to_names = dict(enumerate(months, start=1))
>>> months_nums_to_names
{1: 'Jan', 2: 'Feb', 3: 'Mar', 4: 'Apr', 5: 'May', 6: 'Jun', 7: 'Jul', 8: 'Aug', 9: 'Sep', 10: 'Oct', 11: 'Nov', 12: 'Dec'}
>>>
>>> {v: k for k, v in months_nums_to_names.items()} # 这里使用了字典推导式,把字典months_nums_to_names中键值对掉个个。
{'Jan': 1, 'Feb': 2, 'Mar': 3, 'Apr': 4, 'May': 5, 'Jun': 6, 'Jul': 7, 'Aug': 8, 'Sep': 9, 'Oct': 10, 'Nov': 11, 'Dec': 12}
获取文件扩展名的两种方法
在Python中获取文件扩展名的两种方法:
# Python
>>> filename = "carbon.png"
>>> from os.path import splitext
>>> splitext(filename)[-1]
'.png'
>>> from pathlib import Path
>>> Path(filename).suffix
'.png'
获取日历月
在Python中获取日历月的两种方法:
# Python
>>> import calendar
>>> print(calendar.month(2021, 4))
April 2021
Mo Tu We Th Fr Sa Su
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30
# 想要一个列表中的列表(矩阵)来代替上面的结果吗?
>>> from pprint import pprint as pp
>>> pp(calendar.monthcalendar(2021, 4))
[[0, 0, 0, 1, 2, 3, 4],
[5, 6, 7, 8, 9, 10, 11],
[12, 13, 14, 15, 16, 17, 18],
[19, 20, 21, 22, 23, 24, 25],
[26, 27, 28, 29, 30, 0, 0]]
通过编程制作gif图
imageio
是一个整洁的库,可以借助它通过编程的方式制作gif。
这里我们用它来制作从某个网站上所获取的4个图片的gif文件。
# Python
>>> twitter_img_url = "https://pbs.twimg.com/media/{}?format=jpg&name=small"
>>> tip_images = "Eze6FmFXsAATgRx Eze5EJQWUAEMP9y EzZvI3xX0AE75p_ EzT-nI9UYAEuTr4".split()
>>> from urllib.request import urlretrieve
>>> for img in tip_images:
... urlretrieve(twitter_img_url.format(img), img)
...
>>> import imageio
>>> images = [imageio.imread(filename) for fileneme in tip_images]
>>> imageio.mimsave("tips.gif", images, duration=1)
由于上面的网址无法访问,所以用当前目录下的4个图片文件实现生成gif文件的目的:
当前目录下有下列的图片文件:
2021-05-13-11-54-01.png
2021-05-19-10-29-48.png
2021-05-21-11-00-42.png
2021-05-21-14-05-34.png
2021-05-21-15-20-29.png
2021-05-28-11-25-06.png
2021-05-28-11-31-13.png
2021-05-28-11-44-46.png
2021-05-28-11-53-05.png
2021-05-28-14-01-50.png
2021-05-28-14-16-31.png
2021-05-28-14-18-12.png
2021-05-28-14-23-45.png
NLTK_Downloader.png
除了这些扩展名为.png
的图片文件外,当前目录下还有其他文件,另外,我们只想使用图片文件列表中第2、3、4、5个图片形成最终的gif文件:
# Python
import os
import imageio
img_list=[]
for i in os.listdir(): #遍历当前文件夹中的所有文件
if os.path.splitext(i)[1] == ".png": # 判断文件扩展名是否为“.png”,如果是,则加入列表。
img_list.append(i)
images = [imageio.imread(fileneme) for fileneme in img_list[1:5]]
imageio.mimsave("new_img.gif", images, duration=1)
效果如下:
获取文件名
从Python中的文件路径获取文件名的两种方法:
# Python
>>> file = "/Users/bobbelderbos/Downloads/carbon.png"
>>>
>>> import os
>>> os.path.basename(file)
'carbon.png'
>>>
>>> from pathlib import Path
>>> Path(file).name
'carbon.png'
faker
包生成虚拟数据
您的应用需要使用一些虚拟数据吗?使用faker
包吧,里面有很多东西!
# Python
>>> from faker import Faker
>>> fake = Faker()
>>> dir(fake)
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattr__', '__getattribute__', ..., 'windows_platform_token', 'word', 'words', 'year', 'zip', 'zipcode', 'zipcode_in_state', 'zipcode_plus4']
>>> fake.words()
['spend', 'area', 'president']
>>> fake.words()
['blue', 'century', 'leave']
>>> fake.words()
['tend', 'standard', 'difference']
>>> fake.zipcode()
'84447'
>>> fake.first_name()
'Amy'
>>> fake.last_name()
'Hughes'
>>> fake.last_name()
'Perez'
>>> fake.email()
'[email protected]'
>>> fake.swift()
'UEINGBRDX3O'
用itertools.product
替换嵌套的for
循环
有时用Python的itertools.product
来替换嵌套的for
循环会很有趣:
# Python
>>> for i in range(1, 4):
... for j in "AB":
... print(f"{i}{j}")
...
1A
1B
2A
2B
3A
3B
>>> from itertools import product
>>> for (i, j) in product(range(1, 4), "AB"):
... print(f"{i}{j}")
...
1A
1B
2A
2B
3A
3B
使用itertools
进行排列组合
另外一个itertools
的技巧:
问题:给定一个朋友列表,可以形成多少对?
“组合(combinations)”是你的朋友。
“排列(permutations)”在这里不起作用,因为它根据元素的位置将元素视为唯一的,因此 Ana+Juliette 和 Juliette+Ana 被认为是不同的。
# Python
>>> friends = ["Fernando", "Ana", "juliette"]
>>> from itertools import combinations, permutations
>>> list(combinations(friends, 2))
[('Fernando', 'Ana'), ('Fernando', 'juliette'), ('Ana', 'juliette')]
>>> list(permutations(friends, 2))
[('Fernando', 'Ana'), ('Fernando', 'juliette'), ('Ana', 'Fernando'), ('Ana', 'juliette'), ('juliette', 'Fernando'), ('juliette', 'Ana')]
使用itertools.accumulate
计算运行和:
您可以使用Python的itertools.accumulate
来计算运行和:
# Python
>>> from itertools import accumulate
>>> sales = [22, 23, 26, 29, 34, 42]
>>> list(accumulate(sales))
[22, 45, 71, 100, 134, 176]
内置函数zip
Python的内置函数zip
可以在序列上循环两次,并将当前项与前一项进行比较:
# Python
>>> sales = [22, 23, 26, 29, 34, 42]
>>> for yesterday, today in zip(sales, sales[1:]):
... print(today - yesterday)
...
1
3
3
5
8
用Python比较两个文件的内容
以下是用Python 中两个文件的方法:
# Python
>echo "hello" > file1
>echo "hello" > file2
>echo "hello world" > file3
>python
>>> import filecmp
>>> filecmp.cmp("file1", "file2")
True
>>> filecmp.cmp("file1", "file3")
False
string
模块中的常量
我们都不喜欢重新发明轮子!
Python的string
模块中有一些有用的常量,可以在代码中使用它们:
# Python
>>> import string
>>> dir(string)
['Formatter', 'Template', '_ChainMap', '_TemplateMetaclass', '__all__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', '_re', '_sentinel_dict', '_string', 'ascii_letters', 'ascii_lowercase', 'ascii_uppercase', 'capwords', 'digits', 'hexdigits', 'octdigits', 'printable', 'punctuation', 'whitespace']
>>> string.digits
'0123456789'
>>> string.punctuation
'!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~'
集合(set
)与字典(dictionary
)推导式
列表推导式虽然很棒,但是在Python 中还有set
和dictionary
的推导式,它们也非常简洁。
下面的例子中,过滤包含“a”的名称并使用集合推导对其进行去重。 类似地,我们可以使用字典推导式将值与每个名称相关联。
# Python
>>> names = ["Dana", "Ana", "Sara", "Amber", "Joyce", "Dana", "Tim", "Ana"]
>>> {name for name in names if "a" in name.lower()}
{'Amber', 'Sara', 'Ana', 'Dana'} # 集合推导式
>>> {name: 0 for name in names if "a" in name.lower()}
{'Dana': 0, 'Ana': 0, 'Sara': 0, 'Amber': 0} # 字典推导式
反转列表
如何在Python中反转列表?有两种方法:
# Python
>>> # 方法一
>>> numbers = [1, 2, 3, 4, 5]
>>> # in place
>>> numbers.reverse()
>>> numbers
[5, 4, 3, 2, 1]
>>> # returning a copy
>>> list(reversed(numbers))
[1, 2, 3, 4, 5]
>>> numbers
[5, 4, 3, 2, 1]
>>> # 方法二:
>>> numbers[::-1]
[1, 2, 3, 4, 5]
千分号
Python允许您给数字添加下划线。
这是一种使比较大的数字更具可读性的有用技术,比如表示千分号:
# Python
>>> 1000000000 == 1_000_000_000
True
在Python中需要一个唯一的 ID
想要在Python 中使用一个唯一的 ID吗? 请使用uuid
模块:
# Python
>>> from uuid import uuid4
>>> uuid4()
UUID('0639eff6-d86b-4170-9a45-d9bef6cca5cb')
让正则表达式停止匹配
正则表达式是贪婪的!
添加一个?
使正则表达式不再贪婪; 一旦满足了匹配条件,正则表达式就会停止。
所以在这个例子中(是的,对于HTML解析使用一个库,这只是为了举例)我们这样匹配第一段:
# Python
>>> import re
>>> html = "Some text.
Some more text.
"
>>> re.search(".*
", html).group()
'Some text.
Some more text.
'
>>> re.search(".*?
", html).group()
'Some text.
'
过滤器+lambda
与列表表达式
Python的过滤器+lambda
还是列表表达式,你喜欢哪个?
# Python
>>> languages = ["Python", "Java", "Perl", "JS", "C++", "Ruby"]
>>> list(filter(lambda lang: lang.startswith("P"), languages))
['Python', 'Perl']
>>> [lang for lang in languages if lang.startswith("P")]
['Python', 'Perl']
dateutil
的模糊解析功能
dateutil
的模糊解析功能:
# Python
>>> from dateutil.parser import parse
>>> date = "Wed Apr 10 22:39"
>>> parse(date)
datetime.datetime(2021, 4, 10, 22, 39)
集合的操作
Python集合操作是非常强大的:
# Python
>>> group1 = "Tim Jake Sara".split()
>>> group2 = "Ed Sara Julian".split()
>>> set(group1) & set(group2)
{'Sara'}
>>> set(group1) ^ set(group2)
{'Julian', 'Ed', 'Tim', 'Jake'}
>>>
>>> set(group1) - set(group2)
{'Tim', 'Jake'}
>>> set(group2) - set(group1)
{'Julian', 'Ed'}
引发HTTPError
Python的requests
库有一个raise_for_status()
方法,该方法在错误请求的情况下会引发 HTTPError:
# Python
>>> import requests
>>> resp = requests.get("https://httpbin.org/status/404")
>>> resp.status_code
404
>>> resp.raise_for_status()
Traceback (most recent call last):
File "", line 1, in
File "D:\Program Files\Python38\lib\site-packages\requests\models.py", line 943, in raise_for_status
raise HTTPError(http_error_msg, response=self)
requests.exceptions.HTTPError: 404 Client Error: NOT FOUND for url: https://httpbin.org/status/404
使用urlparse
将url解析为不同的组件
您可以使用urlparse
将url解析为不同的组件:
# Python
>>> url = "https://pybit.es/lessons-from-wooden.html?referer=Twitter"
>>> from urllib.parse import urlparse
>>> parts = urlparse(url)
>>> parts
ParseResult(scheme='https', netloc='pybit.es', path='/lessons-from-wooden.html', params='', query='referer=Twitter', fragment='')
一行程序验证IP地址
在Python中验证IP地址的一行程序:
# Python
>>> import ipaddress
>>> ipaddress.ip_address("192.168.0.2")
IPv4Address('192.168.0.2')
>>> ipaddress.ip_address("1.0x2.3.4")
Traceback (most recent call last):
File "", line 1, in
File "D:\Program Files\Python38\lib\ipaddress.py", line 53, in ip_address
raise ValueError('%r does not appear to be an IPv4 or IPv6 address' %
ValueError: '1.0x2.3.4' does not appear to be an IPv4 or IPv6 address
itertools.cycle
无限循环一个序列
使用itertools.cycle无限循环一个序列,这里我们模拟一个红绿灯:
# Python
>>> from itertools import cycle
>>> lights = "Red Green Amber".split()
>>> states = cycle(lights)
>>> next(states)
'Red'
>>> next(states)
'Green'
>>> next(states)
'Amber'
>>> next(states)
'Red'
>>> next(states)
'Green'
>>> next(states)
'Amber'
用str.translate
返回字符串的副本
Python的str.translate
返回值是某个字符串的副本,但是其中每个字符都已经是通过给定的转换表进行映射后的结果。
例如,我们使用它来交换大小写元音:
# Python
>>> vowels = "aeiou"
>>> table = {c: c.swapcase() for c in vowels + vowels.upper()}
>>> text = "today is a sUnny dAy"
>>> translation = text.maketrans(table)
>>> text.translate(translation)
'tOdAy Is A sunny day'
print()
使用通配符*
Python的print
语句比您想象的更强大:
# Python
>>> name = ["Julian", "Bob", "Martin", "Rodolfo"]
>>> print(*name, sep="\n")
Julian
Bob
Martin
Rodolfo
您可以使用textwrap
模块把文本转换成相同列宽的处理:
# Python
>>> text = ("Every great developer you know got there by solving "
... "probelems they were unqualified to solve until they "
... "actuallly did it. - Patrick Mckenzie")
>>> from textwrap import wrap
>>> from pprint import pprint as pp
>>> pp(wrap(text, width=40))
['Every great developer you know got there',
'by solving probelems they were',
'unqualified to solve until they',
'actuallly did it. - Patrick Mckenzie']
>>>
>>> print(wrap(text, width=40))
['Every great developer you know got there', 'by solving probelems they were', 'unqualified to solve until they', 'actuallly did it. - Patrick Mckenzie']
zip_logest
的用法
如果您不希望内建的zip
被截断,您可以使用itertools
模块中的 zip_longest
:
# Python
>>> names = "ed sarah jake tim george".split()
>>> scores = (11, 22, 33, 44)
>>> dict(zip(names, scores))
{'ed': 11, 'sarah': 22, 'jake': 33, 'tim': 44}
>>> from itertools import zip_longest
>>> dict(zip_longest(names, scores))
{'ed': 11, 'sarah': 22, 'jake': 33, 'tim': 44, 'george': None}
open
方法的x
开关
Python的open
内置方法有一个x
开关,用于打开文件进行“独占创建”,如果文件已经存在,则会失败:
# Python
>echo file.txt
file.txt
>python
>>> with open("file.txt", "x") as f:
... f.write("some text")
>>>9
查找子字符串在字符串中的位置
可以使用find()
或rfind()
查找子字符串在字符串中的位置:
# Python
>>> text = "today is a beautiful day"
>>> text.find("day")
2
>>> text.rfind("day")
21
>>> text[text.rfind("day"):]
'day'
>>> text.find("dayy")
-1
通过数字查找月份名称,通过月份名称查找数字
可以使用calendar.month_abbr
从数字中查找月份名称,反之亦然:
# Python
>>> import calendar
>>> {month: index for index, month in enumerate(calendar.month_abbr) if month}
{'Jan': 1, 'Feb': 2, 'Mar': 3, 'Apr': 4, 'May': 5, 'Jun': 6, 'Jul': 7, 'Aug': 8, 'Sep': 9, 'Oct': 10, 'Nov': 11, 'Dec': 12}
>>> # 或者想要查找月份的数字:
>>> {index: month for index, month in enumerate(calendar.month_abbr) if month}
{1: 'Jan', 2: 'Feb', 3: 'Mar', 4: 'Apr', 5: 'May', 6: 'Jun', 7: 'Jul', 8: 'Aug', 9: 'Sep', 10: 'Oct', 11: 'Nov', 12: 'Dec'}
Python #tip:您可以使用函数的__annotations__
属性检查函数的注释:
# Python
>>> def hello(name: str) ->str:
... return f"Hello {name}"
...
>>> hello.__annotations__
{'name': , 'return': }
python-decouple
与python-dotenv
库
按照Django的应用程序(app
)的要求,您应该在环境中存储配置。
而python-decouple
与python-dotenv
库则是用于此目的两个非常优秀的库,比如:
# Python
from decouple import config, Csv
SECRET_KEY = config("SECRET_KEY")
DEBUG = config("DEBUG", default=False, cast=bool)
ALLOWED_HOSTS = config("ALLOWER_HOSTS", cast = Csv())
注:脚本中的decouple来自于
python-decouple
库的安装,而不是decouple
,所以如果在之前误安装了decouple
库(不是python-decouple
库),则需要把使用pip uninstall decouple
命令把不带“python-”前缀的decouple
库卸载掉,否则在执行from decouple import config
语句时,会出现如下的错误信息:
ImportError: cannot import name 'config' from 'decouple'
(D:\Program Files\Python38\lib\site-packages\decouple\__init__.py)
splitlines()
函数
Python的splitlines()
适用于换行符 ("\n") 和回车符 ("\r"):
# Python
>>> line = "some text\r\nsome more text"
>>> line.split("\n")
['some text\r', 'some more text']
>>> line.splitlines()
['some text', 'some more text']
>>>
让字符串的长度相等
如果希望字符串的宽度相等,可以使用zfill()
方法,该方法在开始处添加零:
# Python
>>> for i in range(1, 11):
... str(i).zfill(3)
...
'001'
'002'
'003'
'004'
'005'
'006'
'007'
'008'
'009'
'010'
对生成器(Generator)进行切片:
您可以使用itertools.islice
对生成器(Generator)进行切片:
# Python
>>> def gen():
... yield from range(1, 11)
...
>>> g = gen()
>>> g[:2]
Traceback (most recent call last):
File "", line 1, in
TypeError: 'generator' object is not subscriptable
>>> from itertools import islice
>>> list(islice(g, 3, 5))
[4, 5]
any
函数
Python很简洁,读起来就像英语一样!
一个很好的例子就是在本例中将 4 行代码减少为一行代码的any
内置函数:
# Python
>>> languages = ["Java", "Perl", "PHP", "Python", "JS", "C++", "JS", "Ruby"]
>>> has_pluses = False
>>> for language in languages:
... if "++" in language:
... has_pluses = True
...
>>> has_pluses
True
>>> # 更Python化、更简洁的方式:
>>> any("++" in language for language in languages)
True
删除序列中的重复项
可以使用集合对序列中的项目进行重复数据删除。请注意,它不会保留各个项目在原有序列中的顺序。
# Python
>>> languages = [
... "Python", "Java", "Perl", "PHP",
... "Python", "JS", "C++", "JS",
... "Python", "Ruby",
... ]
>>> languages.count("Python")
3
>>> set(languages)
{'Python', 'Perl', 'Java', 'JS', 'PHP', 'C++', 'Ruby'}
链式链接比较运算符
在#Python 中,您可以像下满这样链接各个比较运算符:
# Python
>>> a, b = 5, 15
>>> 1 < a and a < 10
True
>>> 1 < a < 10
True
>>> 1 < b and b < 10
False
>>> 1 < b < 10
False
sorted()
与sort()
:
sorted()
返回一个新列表,sort()
就地排序:
# Python
>>> friends = "doug kim anthony sara fred joyce".split()
>>> sorted(friends)
['anthony', 'doug', 'fred', 'joyce', 'kim', 'sara']
>>> friends
['doug', 'kim', 'anthony', 'sara', 'fred', 'joyce']
>>>friends.sort()
>>> friends
>>> ['anthony', 'doug', 'fred', 'joyce', 'kim', 'sara']
获取时间戳:
在Python中获取Unix时间戳很容易:
# Python
>>> import time
>>> time.time()
1622445350.722104
>>> int(time.time())
1622445360
>>> int(time.time())
1622445370
删除缩进和换行
inspect.cleandoc
(或textwrap.dedent
)可以帮助您删除不需要的缩进和换行,这对于测试是非常有用的:
# Python
>>> actual = "123\n456\n789"
>>> print(actual)
123
456
789
>>> expected = """
... 123
... 456
... 789
... """
>>> assert actual == expected
Traceback (most recent call last):
File "", line 1, in
AssertionError
>>> from inspect import cleandoc
>>> cleandoc(expected)
'123\n456\n789'
>>> assert actual == cleandoc(expected)
将字节转换为字符串
有时您需要在Python中将字节转换为字符串,您可以使用decode()
来实现:
# Python
>>> response = b"pragmatic programmer"
>>> type(response)
>>> "pragmatic" in response
Traceback (most recent call last):
File "", line 1, in
TypeError: a bytes-like object is required, not 'str'
>>> response = response.decode("utf-8")
>>> type(response)
>>> "pragmatic" in response
True
f-strings
调试/打印变量:
启动Python 3.8 f-strings可以更轻松地调试/打印变量:
# Python
>>> name = "Jacob"
>>> color = "red"
>>> day = "Saturday"
>>> f"{name=} {color=} {day=}"
"name='Jacob' color='red' day='Saturday'"
让random
模块变得可预测:
使用seed使Python的random
变得可预测:
# Python
>>> from random import choice, seed
>>> names = ("Jake", "Sara", "Charlie", "Amy", "Doug")
>>> seed(123)
>>> choice(names)
'Jake'
>>> choice(names)
'Charlie'
>>> seed(123)
>>> choice(names)
'Jake'
>>> choice(names)
'Charlie'
从序列中选择随机项或进行随机抽样:
Python可以很容易地从序列中选择随机项或进行随机抽样样本:
# Python
>>> colors = ("red", "green", "yellow", "blue", "grey", "orange")
>>> from random import choice, sample
>>> choice(colors)
'blue'
>>> sample(colors, 3) # 3表示抽样数量,colors是样本
['red', 'green', 'yellow']
sorted()
函数的key
关键字参数(函数形式的表达式)
在Python中,内置函数sorted()
使用一个可选的key
关键字参数(一个函数形式的表达式)进行比较。 在这里,我们使用它按姓氏对学生进行排序:
# Python
>>> students = ["Boblne Scholar", "Clare Cutress",
... "Levey Noton", "Malynda Izatt",
... "Prissie Jeenes"]
>>> def get_last_name(full_name):
... return full_name.split()[-1]
...
>>> sorted(students, key=get_last_name)
['Clare Cutress', 'Malynda Izatt', 'Prissie Jeenes', 'Levey Noton', 'Boblne Scholar']
string.Template
模块
Python的string.Template
模块是提前构建字符串的好方法:
# Python
>>> from string import Template
>>> s = Template("Hey $name, congratulations on your $belt Ninja Belt")
>>> s.substitute(name="Tim", belt="Orange")
'Hey Tim, congratulations on your Orange Ninja Belt'
循环遍历附加一个计数器:
如果在循环遍历一个iterable
时希望值旁边伴随有一个计数器,那么就请使用内置函数enumerate
。你甚至可以从1开始:
# Python
>>> names = ("Sara", "Kevin", "Ana", "Tim", "Elisa")
>>> for i, name in enumerate(names, start=1):
... print(f"{i}, {name}")
...
1, Sara
2, Kevin
3, Ana
4, Tim
5, Elisa
一次从字典中获取多个项目
有没有想过如何一次从字典中获取多个项目?
您可以使用operator
模块中的itemgetter
实现这个功能:
# Python
>>> workouts = {
... "mon": "chest+biceps",
... "tue": "legs",
... "thurs": "back+triceps",
... "frt": "legs"
... }
>>> from operator import itemgetter
>>> itemgetter("mon", "frt")(workouts)
('chest+biceps', 'legs')