Python 连接两个范围函数结果

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14099872/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 10:26:48  来源:igfitidea点击:

Concatenating two range function results

pythonpython-3.xrangeconcatenation

提问by MAG

Does range function allows concatenation ? Like i want to make a range(30)& concatenate it with range(2000, 5002). So my concatenated range will be 0, 1, 2, ... 29, 2000, 2001, ... 5001

range 函数是否允许连接?就像我想制作一个range(30)& 将它与range(2000, 5002). 所以我的连接范围将是0, 1, 2, ... 29, 2000, 2001, ... 5001

Code like this does not work on my latest python (ver: 3.3.0)

这样的代码不适用于我最新的 python (ver: 3.3.0)

range(30) + range(2000, 5002)

回答by Lev Levitsky

You can use itertools.chainfor this:

您可以itertools.chain为此使用:

from itertools import chain
concatenated = chain(range(30), range(2000, 5002))
for i in concatenated:
     ...

It works for arbitrary iterables. Note that there's a difference in behavior of range()between Python 2 and 3 that you should know about: in Python 2 rangereturns a list, and in Python3 an iterator, which is memory-efficient, but not always desirable.

它适用于任意迭代。请注意,range()您应该了解 Python 2 和 3 之间的行为差异:在 Python 2 中range返回一个列表,而在 Python3 中返回一个迭代器,它具有内存效率,但并不总是可取的。

Lists can be concatenated with +, iterators cannot.

列表可以与 连接+,迭代器不能。

回答by Andreas Jung

range()in Python 2.x returns a list:

range()在 Python 2.x 中返回一个列表:

>>> range(10)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

xrange()in Python 2.x returns an iterator:

xrange()在 Python 2.x 中返回一个迭代器:

>>> xrange(10)
xrange(10)

And in Python 3 range()also returns an iterator:

在 Python 3 中range()也返回一个迭代器:

>>> r = range(10)
>>> iterator = r.__iter__()
>>> iterator.__next__()
0
>>> iterator.__next__()
1
>>> iterator.__next__()
2

So it is clear that you can not concatenate iterators other by using chain()as the other guy pointed out.

所以很明显,你不能chain()像其他人指出的那样使用其他的迭代器连接。

回答by Inbar Rose

Can be done using list-comprehension.

可以使用list-comprehension来完成。

>>> [i for j in (range(10), range(15, 20)) for i in j]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 15, 16, 17, 18, 19]

Works for your request, but it is a long answer so I will not post it here.

适用于您的要求,但这是一个很长的答案,所以我不会在这里发布。

note: can be made into a generator for increased performance:

注意:可以制成发电机以提高性能:

for x in (i for j in (range(30), range(2000, 5002)) for i in j):
    # code

or even into a generator variable.

甚至进入生成器变量。

gen = (i for j in (range(30), range(2000, 5002)) for i in j)
for x in gen:
    # code

回答by pepr

I like the most simple solutions that are possible (including efficiency). It is not always clear whether the solution is such. Anyway, the range()in Python 3 is a generator. You can wrap it to any construct that does iteration. The list()is capable of construction of a list value from any iterable. The +operator for lists does concatenation. I am using smaller values in the example:

我喜欢可能的最简单的解决方案(包括效率)。解决方案是否如此并不总是很清楚。无论如何,range()Python 3 中的 是一个生成器。您可以将它包装到任何进行迭代的构造中。在list()能够从建设任何可迭代列表值的。该+系列表符不串联。我在示例中使用较小的值:

>>> list(range(5))
[0, 1, 2, 3, 4]
>>> list(range(10, 20))
[10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
>>> list(range(5)) + list(range(10,20))
[0, 1, 2, 3, 4, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]

This is what range(5) + range(10, 20)exactly did in Python 2.5 -- because range()returned a list.

range(5) + range(10, 20)正是 Python 2.5 中所做的——因为range()返回了一个列表。

In Python 3, it is only useful if you really want to construct the list. Otherwise, I recommend the Lev Levitsky'ssolution with itertools.chain. The documentation also shows the very straightforward implementation:

在 Python 3 中,只有当你真的想构造列表时它才有用。否则,我推荐使用itertools.chainLev Levitsky解决方案。该文档还显示了非常简单的实现:

def chain(*iterables):
    # chain('ABC', 'DEF') --> A B C D E F
    for it in iterables:
        for element in it:
            yield element

The solution by Inbar Roseis fine and functionally equivalent. Anyway, my +1 goes to Lev Levitsky and to his argument about using the standard libraries. From The Zen of Python...

Inbar Rose的解决方案很好,功能相当。无论如何,我的 +1 给 Lev Levitsky 和他关于使用标准库的论点。从Python 之禅...

In the face of ambiguity, refuse the temptation to guess.

面对模棱两可,拒绝猜测的诱惑。

#!python3
import timeit
number = 10000

t = timeit.timeit('''\
for i in itertools.chain(range(30), range(2000, 5002)):
    pass
''',
'import itertools', number=number)
print('itertools:', t/number * 1000000, 'microsec/one execution')

t = timeit.timeit('''\
for x in (i for j in (range(30), range(2000, 5002)) for i in j):
    pass
''', number=number)
print('generator expression:', t/number * 1000000, 'microsec/one execution')

In my opinion, the itertools.chainis more readable. But what really is important...

在我看来,itertools.chain它更具可读性。但真正重要的是...

itertools: 264.4522138986938 microsec/one execution
generator expression: 785.3081048010291 microsec/one execution

... it is about 3 times faster.

...它大约快 3 倍。

回答by Darknight

With the help of the extend method, we can concatenate two lists.

在扩展方法的帮助下,我们可以连接两个列表。

>>> a = list(range(1,10))
>>> a.extend(range(100,105))
>>> a  
[1, 2, 3, 4, 5, 6, 7, 8, 9, 100, 101, 102, 103, 104]

回答by raphael

I came to this question because I was trying to concatenate an unknown number of ranges, that might overlap, and didn't want repeated values in the final iterator. My solution was to use setand the unionoperator like so:

我来到这个问题是因为我试图连接未知数量的范围,这些范围可能重叠,并且不想在最终迭代器中出现重复的值。我的解决方案是像这样使用setunion操作符:

range1 = range(1,4)
range2 = range(2,6)
concatenated = set.union(set(range1), set(range2)
for i in concatenated:
    print(i)

回答by cs95

python >= 3.5

蟒蛇> = 3.5

You can use iterable unpacking in lists (see PEP 448: Additional Unpacking Generalizations).

您可以在列表中使用可迭代解包(请参阅 PEP 448: Additional Unpacking Generalizations)。

If you need a list,

如果你需要一份清单,

[*range(2, 5), *range(3, 7)]
# [2, 3, 4, 3, 4, 5, 6]

This preserves order and does not remove duplicates. Or, you might want a tuple,

这会保留顺序并且不会删除重复项。或者,你可能想要一个元组,

(*range(2, 5), *range(3, 7))
# (2, 3, 4, 3, 4, 5, 6)

... or a set,

...或一组,

# note that this drops duplicates
{*range(2, 5), *range(3, 7)}
# {2, 3, 4, 5, 6}

It also happens to be faster than calling itertools.chain.

它也恰好比调用itertools.chain.

from itertools import chain

%timeit list(chain(range(10000), range(5000, 20000)))
%timeit [*range(10000), *range(5000, 20000)]

738 μs ± 10.4 μs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
665 μs ± 13.8 μs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

The benefit of chain, however, is that you can pass an arbitrary list of ranges.

chain但是,的好处是您可以传递任意范围列表。

ranges = [range(2, 5), range(3, 7), ...]
flat = list(chain.from_iterable(ranges))

OTOH, unpacking generalisations haven't been "generalised" to arbitrary sequences, so you will still need to unpack the individual ranges yourself.

OTOH,解包概括尚未“泛化”到任意序列,因此您仍然需要自己解包各个范围。

回答by Tuchar Das

You can use list function around range function to make a list LIKE THIS

您可以在 range 函数周围使用 list 函数来制作像这样的列表

list(range(3,7))+list(range(2,9))