python sum() 导入numpy后结果不同

2022-01-09 00:00:00 python numpy sum

问题描述

我遇到了 Jake VanderPlas 提出的这个问题,我不确定我对导入 numpy 模块后结果为何不同的理解是否完全正确.

I came across this problem by Jake VanderPlas and I am not sure if my understanding of why the result differs after importing the numpy module is entirely correct.

>>print(sum(range(5),-1)
>> 9
>> from numpy import *
>> print(sum(range(5),-1))
>> 10

似乎在第一种情况下,sum 函数计算迭代的总和,然后从总和中减去第二个 args 值.

It seems like in the first scenario the sum function calculates the sum over the iterable and then subtracts the second args value from the sum.

在第二种情况下,在导入 numpy 后,函数的行为似乎发生了变化,因为第二个 arg 用于指定执行求和的轴.

In the second scenario, after importing numpy, the behavior of the function seems to have modified as the second arg is used to specify the axis along which the sum should be performed.

练习编号 (24)来源 - http://www.labri.fr/perso/nrougier/teaching/numpy.100/index.html

Exercise number (24) Source - http://www.labri.fr/perso/nrougier/teaching/numpy.100/index.html


解决方案

只添加我的5个迂腐币到@Warren Weckesser 回答.真的 from numpy import * 不会覆盖 builtins sum 函数,它只是阴影 __builtins__.sum,因为 from ... import * 语句将导入模块中定义的所有名称(以下划线开头的名称除外)绑定到您当前的 global 命名空间.并且根据 Python 的名称解析规则(非官方 LEGB 规则),global 命名空间在 __builtins__ 命名空间之前查找.因此,如果 Python 找到所需的名称,在您的情况下为 sum,它会返回绑定的对象并且不会进一步查找.

Only to add my 5 pedantic coins to @Warren Weckesser answer. Really from numpy import * does not overwrite the builtins sum function, it only shadows __builtins__.sum, because from ... import * statement binds all names defined in the imported module, except those beginning with an underscore, to your current global namespace. And according to Python's name resolution rule (unofficialy LEGB rule), the global namespace is looked up before __builtins__ namespace. So if Python finds desired name, in your case sum, it returns you the binded object and does not look further.

编辑:向您展示发生了什么:

EDIT: To show you what is going on:

 In[1]: print(sum, ' from ', sum.__module__)    # here you see the standard `sum` function
Out[1]: <built-in function sum>  from  builtins

 In[2]: from numpy import *                     # from here it is shadowed
        print(sum, ' from ', sum.__module__)
Out[2]: <function sum at 0x00000229B30E2730>  from  numpy.core.fromnumeric

 In[3]: del sum                                 # here you restore things back
        print(sum, ' from ', sum.__module__)
Out[3]: <built-in function sum>  from  builtins

第一个说明:del 不会删除对象,它是垃圾收集器的任务,它只是取消引用"名称绑定并从当前命名空间中删除名称.

First note: del does not delete objects, it is a task of garbage collector, it only "dereference" the name-bindings and delete names from current namespace.

第二个说明:内置sum函数的签名是sum(iterable[, start]):

startiterable 的项目从左到右求和并返回总数.start 默认为 0.iterable的item一般是数字,起始值不允许是字符串.

Sums start and the items of an iterable from left to right and returns the total. start defaults to 0. The iterable‘s items are normally numbers, and the start value is not allowed to be a string.

我你的情况 print(sum(range(5),-1) 用于内置 sum 总和以 -1 开头.所以从技术上讲,你的短语 iterable 的总和,然后从总和中减去第二个 args 值 是不正确的.对于数字,以 或 add/subtract<开始并不重要/em> 稍后.但是对于列表它确实如此(愚蠢的例子只是为了展示这个想法):

I your case print(sum(range(5),-1) for built-in sum summation starts with -1. So technically, your phrase the sum over the iterable and then subtracts the second args value from the sum isn't correct. For numbers it's really does not matter to start with or add/subtract later. But for lists it does (silly example only to show the idea):

 In[1]: sum([[1], [2], [3]], [4])
Out[1]: [4, 1, 2, 3]               # not [1, 2, 3, 4]

希望这能澄清你的想法:)

Hope this will clarify your thoughts :)

相关文章