range函数python
Python’s built-in range
function is a handy tool to know you need to perform an action a specific number of times.
Python的内置range
函数是一种方便的工具,可以知道您需要执行特定次数的操作。
By the end of this article, you’ll:
到本文结尾,您将:
- Understand how Python’s
range
function works - Know how the implementations differ in Python 2 and Python 3
- Have seen a number of hands-on
range()
examples - Be equipped to work around some of its limitations
- 了解Python的
range
函数如何工作 - 了解Python 2和Python 3中的实现方式有何不同
- 看到了许多动手的
range()
示例 - 有能力克服一些局限性
Let’s get cracking!
让我们开始吧!
Free Bonus: Click here to get our free Python Cheat Sheet that shows you the basics of Python 3, like working with data types, dictionaries, lists, and Python functions.
免费红利: 单击此处可获得我们的免费Python备忘单 ,其中显示了Python 3的基础知识,例如使用数据类型,字典,列表和Python函数。
range()
的历史 (The History of range()
)
Although range()
in Python 2 and range()
in Python 3 may share a name, they are entirely different animals. In fact, range()
in Python 3 is just a renamed version of a function that is called xrange
in Python 2.
虽然range()
在Python 2和range()
在Python 3可以共享一个名字,它们是完全不同的动物。 实际上,Python 3中的range()
只是该函数的重命名版本,在Python 2中称为xrange
。
Originally, both range()
and xrange()
produced numbers that could be iterated over with for-loops, but the former generated a list of those numbers all at once while the latter produced numbers lazily, meaning numbers were returned one at a time as they were needed.
最初, range()
和xrange()
生成可以用for循环迭代的数字,但是前者一次生成所有这些数字的列表,而后者则懒惰地生成数字,这意味着数字一次返回一个他们是需要的。
Having huge lists hang around takes up memory, so it’s no surprise that xrange()
replaced range()
, name and all. You can read more about this decision and the xrange()
vs range()
background in PEP 3100.
闲逛着巨大的清单会占用内存,因此xrange()
取代了range()
,name和all不足为奇。 您可以在PEP 3100中阅读有关此决定以及xrange()
与range()
背景的更多信息。
Note: PEP stands for Python Enhancement Proposal. PEPs are documents that can cover a wide range of topics, including proposed new features, style, governance, and philosophy.
注意: PEP代表Python增强建议。 PEP是可以涵盖广泛主题的文档,包括建议的新功能,样式,治理和理念。
There are a ton of them. PEP 1 explains how they work and is a great place to start.
For the rest of this article, you’ll be using the function as it exists in Python 3.
在本文的其余部分,您将使用Python 3中存在的函数。
Here we go!
开始了!
让我们循环 (Let’s Loop)
Before we dive into seeing how range()
works, we need to take a look at how looping works. Looping is a key computer science concept. If you want to be a good programmer, mastering loops is among the first steps you need to take.
在深入研究range()
工作原理之前,我们需要看一下循环的工作原理。 循环是计算机科学的关键概念 。 如果您想成为一名优秀的程序员,那么掌握循环就是您需要采取的第一步。
Here’s an example of a for-loop in Python:
这是Python中for循环的示例:
captains captains = = [[ 'Janeway''Janeway' , , 'Picard''Picard' , , 'Sisko''Sisko' ]
]
for for captain captain in in captainscaptains :
:
printprint (( captaincaptain )
)
The output looks like this:
输出看起来像这样:
As you can see, a for-loop enables you to execute a specific block of code however many times you want. In this case, we looped through a list of captains and printed each of their names.
如您所见,for循环使您可以执行任意次数的特定代码块。 在这种情况下,我们循环浏览了一系列队长并打印了他们的每个名字。
Although Star Trek is great and everything, you may want to do more than simply loop through a list of captains. Sometimes, you just want to execute a block of code a specific number of times. Loops can help you do that!
尽管《星际迷航》非常出色,但您可能要做的不只是简单地浏览一系列队长。 有时,您只想执行一段特定次数的代码。 循环可以帮助您做到这一点!
Try the following code with numbers that are divisible by three:
尝试使用下面的代码将其数字除以三:
numbers_divisible_by_three numbers_divisible_by_three = = [[ 33 , , 66 , , 99 , , 1212 , , 1515 ]
]
for for num num in in numbers_divisible_by_threenumbers_divisible_by_three :
:
quotient quotient = = num num / / 3
3
printprint (( "" {}{} divided by 3 is divided by 3 is {}{} ."." .. formatformat (( numnum , , intint (( quotientquotient )))
)))
The output of that loop will look like this:
该循环的输出将如下所示:
That’s the output we wanted, so the loop got the job done adequately, but there is another way to get the same result by using range()
.
这就是我们想要的输出,因此循环充分完成了工作,但是还有另一种方法可以通过使用range()
获得相同的结果。
Note: That last code example had some string formatting. To learn more on that topic, you can check out Python String Formatting Best Practices and Python 3’s f-Strings: An Improved String Formatting Syntax (Guide).
注意:最后一个代码示例具有一些字符串格式。 要了解有关该主题的更多信息,可以查看Python字符串格式化最佳实践和Python 3的f字符串:改进的字符串格式化语法(指南) 。
Now that you’re more familiar with loops, let’s see how you can use range()
to simplify your life.
现在您对循环更加熟悉了,让我们看看如何使用range()
简化生活。
range()
入门 (Getting Started With range()
)
So how does Python’s range
function work? In simple terms, range()
allows you to generate a series of numbers within a given range. Depending on how many arguments you pass to the function, you can decide where that series of numbers will begin and end as well as how big the difference will be between one number and the next.
那么Python的range
函数如何工作? 简单来说, range()
允许您在给定范围内生成一系列数字。 根据传递给函数的参数数量,您可以确定该系列数字在何处开始和结束以及一个数字与下一个数字之间的差值有多大。
Here’s a sneak peek of range()
in action:
这是一个作用range()
偷看:
for for i i in in rangerange (( 33 , , 1616 , , 33 ):
):
quotient quotient = = i i / / 3
3
printprint (( "" {}{} divided by 3 is divided by 3 is {}{} ."." .. formatformat (( ii , , intint (( quotientquotient )))
)))
In this for-loop, you were able to simply create a range of numbers that are divisible by 3
, so you didn’t have to provide each of them yourself.
在此for循环中,您可以简单地创建一个可被3
整除的数字范围,因此您不必自己提供每个数字。
Note: While this example shows an appropriate use of range()
, it’s usually frowned upon to use range()
too often in for-loops.
注意:虽然此示例显示了range()
的适当用法,但在for循环中经常不建议使用range()
。
For example, the following use of range()
would generally be considered not Pythonic:
例如,以下range()
使用通常被认为不是Pythonic:
range()
is great for creating iterables of numbers, but it’s not the best choice when you need to iterate over data that could be looped over with the in
operator.
range()
非常适合创建数字的可迭代变量,但是当您需要迭代可能用in
运算符循环的数据时,它不是最佳选择。
If you want to know more, check out How to Make Your Python Loops More Pythonic.
如果您想了解更多信息,请查看如何使Python循环更Pythonic 。
There are three ways you can call range()
:
您可以通过三种方式调用range()
:
range(stop)
takes one argument.range(start, stop)
takes two arguments.range(start, stop, step)
takes three arguments.
-
range(stop)
采用一个参数。 -
range(start, stop)
有两个参数。 -
range(start, stop, step)
采用三个参数。
range(stop)
(range(stop)
)
When you call range()
with one argument, you will get a series of numbers that starts at 0
and includes every whole number up to, but not including, the number you have provided as the stop
.
当使用一个参数调用range()
时,您将获得一系列从0
开始的数字,包括从(直到但不包括)作为stop
提供的数字的所有整数。
Here’s what that looks like in practice:
这是实际的情况:
for for i i in in rangerange (( 33 ):
):
printprint (( ii )
)
The output of your loop will look like this:
循环的输出将如下所示:
That checks out: we have all the whole numbers from 0
up to but not including 3
, the number you provided as the stop
.
可以检查出:我们拥有从0
到但不包括3
(您提供为stop
数字)的所有整数。
range(start, stop)
(range(start, stop)
)
When you call range()
with two arguments, you get to decide not only where the series of numbers stops but also where it starts, so you don’t have to start at 0
all the time. You can use range()
to generate a series of numbers from A to B using a range(A, B)
. Let’s find out how to generate a range starting at 1
.
当您使用两个参数调用range()
时,不仅要决定一系列数字的终止位置,而且还要决定其起始位置,因此不必始终从0
开始。 您可以使用range()
使用range(A, B)
生成从A到B的一系列数字。 让我们了解如何生成从1
开始的范围。
Try calling range()
with two arguments:
尝试使用两个参数调用range()
:
for for i i in in rangerange (( 11 , , 88 ):
):
printprint (( ii )
)
Your output will look like this:
您的输出将如下所示:
So far, so good: you have all the whole numbers from 1
(the number you provided as the start
) up to but not including 7
(the number you provided as the stop
).
到目前为止,一切都很好:你必须从所有整数1
(将你作为提供的号码start
了),但不包括7
(你的提供的号码stop
)。
But if you add one more argument, then you’ll be able to reproduce the output you got earlier when you were using the list named numbers_divisible_by_three
.
但是,如果再添加一个参数,则将能够重现您在使用名为numbers_divisible_by_three
的列表时获得的输出。
range(start, stop, step)
(range(start, stop, step)
)
When you call range()
with three arguments, you can choose not only where the series of numbers will start and stop but also how big the difference will be between one number and the next. If you don’t provide a step
, then range()
will automatically behave as if the step
is 1
.
当使用三个参数调用range()
时,您不仅可以选择一系列数字的起始和终止位置,还可以选择一个数字与下一个数字之间的差值。 如果您不提供step
,则range()
将自动表现为step
为1
。
Note: step
can be a positive number or a negative number, but it can’t be 0
:
注意: step
可以是正数或负数,但不能为0
:
>>> range(1, 4, 0)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: range() arg 3 must not be zero
If you try to use 0
as your step, then you’ll get an error.
如果尝试将0
用作步骤,则会收到错误消息。
Now that you know how to use step
, you can finally revisit that loop we saw earlier with division by 3
.
现在,您知道如何使用step
,您终于可以重新访问我们之前看到的除以3
循环。
Try it for yourself:
自己尝试:
for for i i in in rangerange (( 33 , , 1616 , , 33 ):
):
quotient quotient = = i i / / 3
3
printprint (( "" {}{} divided by 3 is divided by 3 is {}{} ."." .. formatformat (( ii , , intint (( quotientquotient )))
)))
Your output will look exactly like the output of the for-loop you saw earlier in this article, when you were using the list named numbers_divisible_by_three
:
您的输出看起来与您在本文前面看到的for循环的输出完全相同,当您使用名为numbers_divisible_by_three
的列表numbers_divisible_by_three
:
As you see in this example, you can use the step
argument to increase towards a higher number. That’s called incrementing.
如本例所示,您可以使用step
参数将其增加到更大的数字。 这就是所谓的增量。
随着range()
递增 (Incrementing With range()
)
If you want to increment, then you need step
to be a positive number. To get an idea of what this means in practice, type in the following code:
如果要递增,则需要将step
设为正数。 要了解这实际上意味着什么,请输入以下代码:
for for i i in in rangerange (( 33 , , 100100 , , 2525 ):
):
printprint (( ii )
)
If your step
is 25
, then the output of your loop will look like this:
如果您的step
是25
,那么循环的输出将如下所示:
You got a range of numbers that were each greater than the preceding number by 25
, the step
you provided.
您得到的数字范围比上一个数字大25
,即您提供的step
。
Now that you’ve seen how you can step forwards through a range, it’s time to see how you can step backwards.
既然您已经了解了如何前进一个范围,那么现在该看看如何后退了。
用range()
递减 (Decrementing With range()
)
If your step
is positive, then you move through a series of increasing numbers and are incrementing. If your step
is negative, then you move through a series of decreasing numbers and are decrementing. This allows you to go through the numbers backwards.
如果您的step
是肯定的,那么您将经历一系列递增的数字并且正在递增。 如果step
为负,则您将经历一系列递减的数字并递减。 这使您可以倒转数字。
In the following example, your step
is -2
. That means that you’ll be decrementing by 2
for each loop:
在以下示例中,您的step
是-2
。 这意味着您将为每个循环递减2
:
for for i i in in rangerange (( 1010 , , -- 66 , , -- 22 ):
):
printprint (( ii )
)
The output of your decrementing loop will look like this:
递减循环的输出将如下所示:
You got a range of numbers that were each smaller than the preceding number by 2
, the absolute value of the step
you provided.
您得到的数字范围均比上一个数字小2
,即您提供的step
的绝对值 。
The most Pythonic way to create a range that decrements is to use range(start, stop, step)
. But Python does have a built-in reversed
function. If you wrap range()
inside reversed()
, then you can print the integers in reverse order.
创建范围减小的最Pythonic方法是使用range(start, stop, step)
。 但是Python确实具有内置的reversed
功能。 如果将range()
包装在reversed()
,则可以按相反的顺序打印整数。
Give this a try:
试试看:
for for i i in in reversedreversed (( rangerange (( 55 )):
)):
printprint (( ii )
)
You’ll get this:
您将获得:
range()
makes it possible to iterate over a decrementing sequence of numbers, whereas reversed()
is generally used to loop over a sequence in reverse order.
range()
可以迭代递减的数字序列,而reversed()
通常用于以相反顺序循环序列。
Note: reversed()
also works with strings. You can learn more about the functionality of reversed()
with strings in How to Reverse a String in Python.
注意: reversed()
也适用于字符串。 您可以在如何在Python中反转字符串中了解有关带有字符串的reversed()
功能的更多信息。
使用range()
更深入 (Going Deeper With range()
)
Now that you know the basics of how to use range()
, it’s time to dig a little deeper.
现在,您已经知道如何使用range()
的基础知识,是时候进行更深入的研究了。
range()
is mainly used for two purposes:
range()
主要用于两个目的:
- Executing the body of a for-loop a specific number of times
- Creating more efficient iterables of integers than can be done using lists or tuples
- 执行for循环的主体特定次数
- 比使用列表或元组创建更有效的整数可迭代
The first use is probably the most common, and you could make the case that itertools gives you a more efficient way to construct iterables than range()
does.
第一次使用可能是最常见的用法,并且可以证明itertools为您提供了比range()
更有效的构造可迭代对象的方法。
Here are a few more points to keep in mind when you use range.
使用范围时,请记住以下几点。
range()
is a type in Python:
range()
是Python中的一种类型:
>>> type(range(3))
<class 'range'>
You can access items in a range()
by index, just as you would with a list:
您可以按索引访问range()
的项目,就像使用列表一样:
>>> range(3)[1]
1
>>> range(3)[2]
2
You can even use slicing notation on a range()
, but the output in a REPL may seem a little strange at first:
您甚至可以在range()
上使用切片符号,但是REPL的输出乍一看似乎有些奇怪:
>>> range(6)[2:5]
range(2, 5)
Although that output may look odd, slicing a range()
just returns another range()
.
尽管该输出可能看起来很奇怪,但是切片range()
只会返回另一个range()
。
The fact that you can access elements of a range()
by index and slice a range()
highlights an important fact: range()
is lazy, unlike a list, but isn’t an iterator.
您可以访问一个元素的事实range()
通过索引和分割一个range()
突出了一个重要的事实: range()
是懒惰的,不像一个列表,但不是一个迭代器 。
浮点数和range()
(Floats and range()
)
You may have noticed that all of the numbers we have been dealing with so far have been whole numbers, which are also called integers. That’s because range()
can take only integers as arguments.
您可能已经注意到,到目前为止,我们一直在处理的所有数字都是整数,也称为整数。 这是因为range()
只能接受整数作为参数。
浮游物语 (A Word on Floats)
In Python, if a number is not a whole number, then it is a float. There are some differences between integers and floats.
在Python中,如果数字不是整数,则为浮点数。 整数和浮点数之间有一些区别。
An integer (int
data type):
整数( int
数据类型):
- Is a whole number
- Does not include a decimal point
- Can be positive, negative, or
0
- 是整数
- 不包含小数点
- 可以为正,负或
0
A floating point number (float
data type):
浮点数( float
数据类型):
- Can be any number that includes a decimal point
- Can be positive or negative
- 可以是任何包含小数点的数字
- 可以是正数或负数
Try calling range()
with a float and see what happens:
尝试用浮点数调用range()
,看看会发生什么:
for for i i in in rangerange (( 3.33.3 ):
):
printprint (( ii )
)
You should get the following error message:
您应该收到以下错误信息:
If you need to find a workaround that will allow you to use floats, then you can use NumPy.
如果需要找到一种允许使用浮点数的解决方法,则可以使用NumPy。
使用NumPy (Using NumPy)
NumPy is a third-party Python library. If you are going to use NumPy, your first step is to check if you have it installed.
NumPy是第三方Python库。 如果要使用NumPy,则第一步是检查是否已安装它。
Here’s how you can do that in your REPL:
您可以在REPL中执行以下操作:
>>> import numpy
If you get a ModuleNotFoundError
, then you need to install it. To do so, go to your command line and enter pip install numpy
.
如果收到ModuleNotFoundError
,则需要安装它。 为此,请转到命令行并输入pip install numpy
。
Once you have it installed, put in the following:
安装完成后,放入以下内容:
import import numpy numpy as as np
np
npnp .. arangearange (( 0.30.3 , , 1.61.6 , , 0.30.3 )
)
It will return this:
它将返回此:
If you want to print each number on its own line, you can do the following:
如果要在每个行上打印每个数字,可以执行以下操作:
import import numpy numpy as as np
np
for for i i in in npnp .. arangearange (( 0.30.3 , , 1.61.6 , , 0.30.3 ):
):
printprint (( ii )
)
This is the output:
这是输出:
Where did 0.8999999999999999
come from?
0.8999999999999999
来自哪里?
Computers have trouble saving decimal floating-point numbers in binary floating-point numbers. This leads to all sorts of unexpected representations of numbers.
计算机在将十进制浮点数保存为二进制浮点数时遇到了麻烦。 这导致各种意外的数字表示。
Note: To learn more about why there are issues representing decimals, you can check out this article and the Python docs.
注意:要了解有关为何存在代表小数的问题的更多信息,可以查看本文和Python文档 。
You might also want to take a look at the decimal library, which is a bit of a downgrade in terms of performance and readability but allows you to represent decimal numbers exactly.
您可能还想看一下十进制库 ,它在性能和可读性方面有些降级,但允许您精确地表示十进制数。
Another option is to use round()
, which you can read more about in How to Round Numbers in Python. Keep in mind that round()
has its own quirks that might generate some surprising results!
另一种选择是使用round()
,您可以在如何在Python中对数字进行四舍五入中了解更多信息。 请记住, round()
有其自身的怪癖,可能会产生一些令人惊讶的结果!
Whether or not these floating point errors are an issue for you depends on the problem you’re solving. The errors are going to be in something like the 16th decimal place, which is insignificant most of the time. They are so small that, unless you’re working on calculating satellite orbital trajectories or something, you don’t need to worry about it.
这些浮点错误是否对您来说是一个问题,取决于您要解决的问题。 错误将在小数点后第16位出现,这在大多数情况下是微不足道的。 它们是如此之小,除非您正在计算卫星轨道轨迹或其他东西,否则您不必担心。
Alternatively, you could also use np.linspace()
. It does essentially the same thing but uses different parameters. With np.linspace()
, you specify start
and end
(both inclusive) as well as the length of the array (instead of step
).
另外,您也可以使用np.linspace()
。 它实际上执行相同的操作,但是使用不同的参数。 使用np.linspace()
,您可以指定start
和end
(包括两端)和数组的长度(而不是step
)。
For instance, np.linspace(1, 4, 20)
gives 20 equally spaced numbers: 1.0, ..., 4.0
. On the other hand, np.linspace(0, 0.5, 51)
gives 0.00, 0.01, 0.02, 0.03, ..., 0.49, 0.50
.
例如, np.linspace(1, 4, 20)
给出20个等间距的数字: 1.0, ..., 4.0
。 在另一方面, np.linspace(0, 0.5, 51)
赋予0.00, 0.01, 0.02, 0.03, ..., 0.49, 0.50
。
Note: To learn more, you can read Look Ma, No For-Loops: Array Programming With NumPy and this handy NumPy reference.
注意:要了解更多信息,您可以阅读Look Ma,No For-Loops:使用NumPy进行数组编程以及此便捷的NumPy参考 。
前进并循环 (Go Forth and Loop)
You now understand how to use range()
and work around its limitations. You also have an idea of how this important function has evolved between Python 2 and Python 3.
现在,您了解了如何使用range()
并解决其局限性。 您还应该了解此重要功能在Python 2和Python 3之间如何演变。
The next time you need to perform an action a specific number of times, you’ll be all set to loop your heart out!
下次您需要执行特定次数的操作时,一切都准备好了!
Happy Pythoning!
快乐的Pythoning!
翻译自: https://www.pybloggers.com/2018/10/pythons-range-function-guide/
range函数python