zfz*_*zfz 5 python ip functional-programming
在python的讨论中,我看到了一个函数,用于将IP字符串转换为函数编程方式的整数.这是链接.
该功能在一行中实现.
def ipnumber(ip):
return reduce(lambda sum, chunk: sum <<8 | chunk, map(int, ip.split(".")))
Run Code Online (Sandbox Code Playgroud)
但是,我对功能编程的想法很少.任何人都可以详细解释这个功能吗?我对"地图"和"减少"有一些了解.但我不知道什么是"|" 而"块"在这里意味着.
谢谢.
Mat*_*lia 13
sum并且chunk是lambda传递给函数的参数reduce.|是二元或运算符.
事情是这样的:
ip.split(".")返回一个字符串列表,每个字符串对应一个虚线字符串("192.168.0.1"=> ["192", "168", "0", "1"];
map将其第一个操作数应用于其第二个操作数的每个元素(["192", "168", "0", "1"]=> [192, 168, 0, 1]);
reduce从列表中获取前两个参数并将其应用于lambda它们; 然后它再次使用lambda的结果和列表的下一个元素; 等等.
的labmda功能(当场定义的匿名功能)执行此:取第一参数,由8个比特,OR值给它的新的块移动它; 因此,会发生的结果是计算结果如下:
(((192<<8 | 168) << 8 | 0)<<8 | 1) = 192<<24 | 168<<16 | 0<<8 | 1
Run Code Online (Sandbox Code Playgroud)
这正是"虚线形式"所代表的(它只是表示32位无符号整数的简写,这就是IP在IPv4中的含义 - 你可以说它有点像在256中表示它)
|是一个按位,逻辑或:
>>> 0 | 1
1
>>> 1 | 1
1
Run Code Online (Sandbox Code Playgroud)
lambda使用当前运行总计和map()函数输出的下一个(整数)值减少调用.所以,它在循环中执行以下操作:
sum = 0
for chunk in map(int, ip.split(".")):
sum = (sum << 8) | chunk
Run Code Online (Sandbox Code Playgroud)
其中map(int, ip.split("."))接通的IP地址为整数的序列; 1.2.3.4成为[1, 2, 3, 4].
这<<是一个按位左移,在这种情况下为8位:
>>> 1 << 8
256
Run Code Online (Sandbox Code Playgroud)
因此,对于ip地址的每个整数部分,它将值向左移动8个位置,并将地址的下一部分的位添加到该数字.
这个非常有意义的,因为IP地址是什么,但一个32位的数字和字符串符号除以该数量最多为4个组块8的位,和"打印"各自那些8位中的一个整数值.在字符之间.
它有助于将每个阶段打印为二进制数:
>>> map(int, '1.2.3.4'.split('.'))
[1, 2, 3, 4]
>>> bin(1)
'0b1'
>>> bin(2)
'0b10'
>>> bin(3)
'0b11'
>>> bin(4)
'0b100'
>>> bin(1 << 8)
'0b100000000'
>>> bin(1 << 8 | 2)
'0b100000010'
>>> bin((1 << 8 | 2) << 8)
'0b10000001000000000'
>>> bin((1 << 8 | 2) << 8 | 3)
'0b10000001000000011'
>>> bin(((1 << 8 | 2) << 8 | 3) << 8)
'0b1000000100000001100000000'
>>> bin(((1 << 8 | 2) << 8 | 3) << 8 | 4)
'0b1000000100000001100000100'
Run Code Online (Sandbox Code Playgroud)