1 简介
本文介绍操作字典及以下内容,
- 按值排序字典: 使用
sorted()
和lambda
或operator.itemgetter()
对字典按值排序。 - 阿姆斯壮数: 定义
isArmstrong()
函数检查是否为阿姆斯壮数,例如153。 - 最大公因数(GCF):
GCF()
函数找到两个数的最大公因数,如8和12的GCF为4。 - 最小公倍数(LCM):
LCM()
函数计算最小公倍数,如24和36的LCM为72。 - 下划线(_)用途: 用于存储解释器最后的表达式值,也可用于忽略解包的值。
- 分隔数字: 使用下划线
`_
在数字中增强可读性,如1_000_000。 - 命名约定:
- 单下划线前缀
_variable
: 通常用于内部使用或避免关键字冲突。 - 双下划线前缀
__variable
: 防止子类继承和直接访问(名称改写)。 - 双下划线前后
__variable__
: 魔术方法或特殊属性,如__init__
。
- 单下划线前缀
每个点都提供了简洁的代码示例来说明其用法。
2 把字典 按 值排序
有如下列表:
a = ['a','a','c','c','b','c']
# d = dict.fromkeys(a,0)
# or
d = {x:0 for x in a}
print(d)
for ch in a:
d[ch] += 1
print(d)
sorted_d = sorted(d.items(), key=lambda x:x[1], reverse=True)
print(sorted_d)
使用 operator.itemgetter() 排序字典
inventory = {'apple': 3,'banana': 2,'pear': 5,'orange': 1}
s = sorted(inventory.items(), key=operator.itemgetter(0))
print(s)
3 查找阿姆斯壮数,阿姆斯特朗数,水仙花数
Armstrong 数,就是n位数的各位数的n次方之和等于该数
例如153可以满足1^3 + 5^3 + 3^3 = 153
def isArmstrong(n):
temp = n
sum = 0
while temp > 0:
sum += (temp % 10)**3
temp //= 10
if n == sum:
return True
return False
n = 1000
print([i for i in range(0,n) if isArmstrong(i)])
# [0, 1, 153, 370, 371, 407]
4 求最大公因数
最大公因数(英语:highest common factor,hcf)也称最大公约数(英语:greatest common divisor,gcd)是数学词汇,指能够整除多个整数的最大正整数。
而多个整数不能都为零。
例如8和12的最大公因数为4.
def GCF(n1,n2):
n = min(n1,n2)
while True:
if n1 % n == 0 and n2 % n == 0:
return n
n -= 1
n1 = 80; n2 = 240
print(GCF(n1,n2))
5 求最小公倍数
两个或多个整数公有的倍数叫做它们的公倍数,其中除0以外最小的一个公倍数就叫做这几个整数的最小公倍数。
整数a,b的最小公倍数记为[a,b],同样的,a,b,c的最小公倍数记为[a,b,c],多个整数的最小公倍数也有同样的记号。
def LCM(n1,n2):
n = max(n1,n2)
while True:
if n % n1 == 0 and n % n2 == 0:
return n
n += 1
n1 = 24; n2 = 36
print(LCM(n1,n2))
6 下划线 _ 的用处
Underscore(_)是Python中的唯一字符
- 在解释器使用
python自动将解释器中最后一个表达式的值存储到名为 _ 的 特定变量中。
如果需要,还可将这些值分配给其他变量
>>> q2.put_noblock(4)
<Future at 0x1b3359d01c0 state=pending>
>>> _
<Future at 0x1b3359d01c0 state=pending>
>>> 6
6
>>> _
6
7 通过下划线忽略值
如果您不想在解包时使用特定值,只需将该值分配给 _
忽略意味着将值分配给 特殊变量 underscore() 我们将值分配给
因为在未来的代码中没有使用它
>>> a, _, b = (1,2,3)
>>> _
2
>>> a, *_, b = (1,2,3,4,5,6)
>>> _
[2,3,4,5]
- 在循环中使用
在循环中 _ 作为变量:
for _ in range(5):
print(_)
8 分隔数字的位数
100万的表示
n = 1_000_000
>>> n = 1_000_000
>>> n
1000000
>>> _ = 1_000_000
>>> _
1000000
二进制
ob_0010
八进制
0o_64
十六进制
>>> 0x_23_ab
9131
9 命名
单前下划线
_variable
class T:
def __init__(self):
self._num = 7
单前下划线 不影响 您访问类的变量
但影响从模块导入的名称,如
# funcimport
def func1():
return "test"
def _func2():
return 1000
from funcimport import *
func1() # 可以运行
test
_func2() # 运行失败
NameError name is not defined
但是可以从模块导入使用
import funcimport
funcimport._func2()
1000
单后下划线
variable_
一般可用于python的关键字命名冲突 避免
None_
print_
都是自定义变量,双前下划线
__variable
双前下划线变量 将不能被子类继承 和更改
也不能都实例 访问
dir中的列表没有 self.__
只有 Sample.__
列表中有self.__c变量吗?
如果您仔细查看属性列表,您会发现一个名为_Sample__c的属性。这就是名字 mangling。这是为了避免在子类中覆盖变量。
>>> class A:
... def __init__(self):
... self.a = 1
... self._b = 2
... self.__c = 3
>>> aa = A()
>>> aa.a
1
>>> aa._b
2
>>> aa.__c
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'A' object has no attribute '__c'
如继承了A的 B 也有 __c属性,但是无法访问
>>> dir(B)
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__'
, '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__
reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__']
>>> dir(bb)
['_A__c', '_B__c', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__',
'__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne_
_', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__
', '__weakref__', '_b', 'a', 'a1']
访问的方式必须是特定的 子类名称
>>> bb._B__c
33
>>> bb._A__c
3
内部函数同样的如属性的访问
>>> class C(B):
... def __init__(self):
... self.a = 111
... self._b = 222
... self.__c = 333
... def __innerfunc(self):
... return 322
>>> cc = C()
>>> cc._C__c
333
>>> cc._C__innerfunc
<bound method C.__innerfunc of <__main__.C object at 0x000001B3359D7EE0>>
>>> cc._C__innerfunc()
322
>>> cc.__innerfunc()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'C' object has no attribute '__innerfunc'
双前后下划线
__variable__
您会发现以双下划线开头和结尾的不同名称。它们被称为魔术方法或dunder 方法。
10 小结
本文示例代码包括按值排序字典、实现阿姆斯壮数函数、GCF与LCM函数,以及使用下划线在循环和解包中。了解下划线在类命名中的规则,如单下划线避免冲突,双下划线进行名称改写和保护成员。