python范围函数不接受序列参数有什么好的理由吗?
正如标题所说,我想知道为什么单参数形式的python范围函数不接受序列参数有什么好的理由吗?,python,loops,numpy,design-patterns,Python,Loops,Numpy,Design Patterns,正如标题所说,我想知道为什么单参数形式的范围内置函数不接受序列作为其参数。我只能看到积极的一面,所以我想知道我是否遗漏了一些明显的东西 考虑到我和我确信很多其他人输入range(somelist)的频率,当他们的意思是range(len(somelist))时,含义应该是显而易见的 我看不出还有什么其他的解释方法 它将消除冗余和一级括号嵌套,并在换行符对可读性特别有害的位置保存键入和线宽 我看不出它会破坏任何代码 所以我的问题是(请不要只是发泄意见) 有没有什么好的(客观的,Python是
范围
内置函数不接受序列作为其参数。我只能看到积极的一面,所以我想知道我是否遗漏了一些明显的东西
- 考虑到我和我确信很多其他人输入
的频率,当他们的意思是range(somelist)
时,含义应该是显而易见的range(len(somelist))
- 我看不出还有什么其他的解释方法
- 它将消除冗余和一级括号嵌套,并在换行符对可读性特别有害的位置保存键入和线宽
- 我看不出它会破坏任何代码
- 有没有什么好的(客观的,Python是可以接受的)论据我可能遗漏了
- 对于
,可能已经有一个方便的函数了吗范围(len(x))
- Python开发人员是否考虑过这一点?如果有,BDFL的立场如何
- 为什么numpy中没有类似于arange的索引?(还是有?)
编辑:我本来希望这不是必要的,但显然是错误的。所以请允许我澄清:这根本不是关于
range
是善还是恶的问题。为了论证起见,让我们接受它是语言的一部分,并从中吸取教训。因为您可以在没有范围的情况下迭代序列:
a = [1,2,3,4]
for item in a:
print(item)
1
2
3
4
如果还需要索引,请使用枚举:
for idx, item in enumerate(a):
print(idx, item)
0 1
1 2
2 3
3 4
如果要组合两个或多个序列,请使用zip
或itertools.zip\u longest
:
for item1, item2 in zip(a, a[::-1]):
print(item1, item2)
1 4
2 3
3 2
4 1
所以实际上(几乎)从来没有理由去做range(len(a))
那么为什么要为它添加一个快捷方式呢
根据Python Zen的说法:
美胜于丑
显式比隐式好
- 考虑到我和我确信许多其他人在表示range(len(somelist))时输入range(somelist)的频率,其含义应该是显而易见的
实际上,这种情况只“经常”发生在新Python用户身上。但迟早(或早比晚好)你应该学会不要那样做。使用索引循环很容易被一个错误关闭。对于somelist中的项,
,正确且类似于python的方法是,如@MSeifert的答案所示
- 它将消除冗余和一级括号嵌套,并在换行符对可读性特别有害的位置保存键入和线宽
我个人认为这不是一个有力的论点。在传统的C/C++表示法中,我们为(inti=0;i定义一个接受该列表输入的函数非常简单:
def lrange(alist):
return range(len(alist))
如果像这样的实用函数能让你的代码变得清晰,那么就使用它。时间开销可以忽略不计
numpy
甚至比核心Python都有很多小函数,它们只是改进输入以适应一个或多个用户组的习惯。提供一个iterable可能没有意义…range('aseqaf')对于instanceIs可能已经有了一个方便的range函数(len(x))是:对于x中的ell:do something
或[ele for ele in x]
。Python已经很好地处理了这一点…@NaN OP不希望range
将iterable分开;他希望隐式调用len
和range(len('aseqaf'))< /代码>和其他任何东西一样。在某些语言中,如“代码> C<代码”。索引是主要的循环工具。<代码> Python < /Cord>鼓励直接在列表上进行迭代。<代码>范围<代码>是生成<代码> C < /C>样式索引的一种方法。<代码>范围< /代码>也采用<代码>开始<代码>和<代码>步骤< /代码> PAR。无法从len()推断的参数
@hpaulj让我这样说吧,您是否支持弃用范围
?这样认为,因为它有它的用途。例如,我不喜欢七个参数zip调用,可能嵌套在枚举中以进行取整。或者以不同的方式将参数剪裁到zip以实现给定的偏移量;非常容易出错,可读性不强。但是不管怎么说,这不是问题。哇,已经有3次接近票数了;这并不需要很长时间。+对于枚举
。如果你需要匹配iterable的索引,这是标准的构造。numpy
有ndenumerate
。是的,对于numpy,还有一堆数组迭代器:nditer
,ndindex
和flatiter
(当然还有前面提到的ndenumerate
):)我真的很想避免这种情况。我们需要range(len(x))栗色,真的有足够多的用途美胜于丑。<好吧,range(a)
比range(len(a))更美。
>显式比隐式好。<我认为在实践中,明确和方便的事情(比如np.one(scalar)
)胜过这一点rule@PaulPanzer“我真的希望避免这种情况,我们需要范围(len(x))在Python中,迭代器协议适用于序列、迭代器和生成器,因此range(len(x))
仅在某些情况下(当它是序列时)才可能使用,而在NumPy中,您很少使用range
或arange
,因为广播使其变得不必要。除了在某些情况下,当一个人使用广播来做非常沉重的事情。所以,是的,有用例,但是(根据禅宗):“特殊的用例不足以打破规则。”在numpy中也有可能:总是有np.mgrid
和np.ogrid
。使用它们创建索引数组(有点)有点烦人:np.mgrid[tuple(map(slice,arr.shape))]
,因为您无法