连接两个范围函数结果

MAG*_*MAG 55 python concatenation range python-3.x

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

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

range(30) + range(2000, 5002)
Run Code Online (Sandbox Code Playgroud)

Lev*_*sky 61

你可以使用itertools.chain这个:

from itertools import chain
concatenated = chain(range(30), range(2000, 5002))
for i in concatenated:
     ...
Run Code Online (Sandbox Code Playgroud)

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

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

  • 请注意:您无法保存链条以供第二次使用。您可以迭代一次。如果你再试一次,你什么也得不到。这与范围的工作方式形成鲜明对比。 (4认同)
  • 对我来说,这一定是 Python 最丑陋的部分之一。对于这样一个基本任务来说,有外部库的要求是荒谬的...... (3认同)

Inb*_*ose 34

可以使用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]
Run Code Online (Sandbox Code Playgroud)

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

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

for x in (i for j in (range(30), range(2000, 5002)) for i in j):
    # code
Run Code Online (Sandbox Code Playgroud)

甚至是发电机变量.

gen = (i for j in (range(30), range(2000, 5002)) for i in j)
for x in gen:
    # code
Run Code Online (Sandbox Code Playgroud)

  • @mkind和Inbar Rose:讨厌依赖可能没问题,但`itertools`模块是标准模块.由于其实现效率更高,使用`itertools.chain`的解决方案速度提高了约3倍 - 请参阅http://stackoverflow.com/a/14101734/1346705.道德是:*"永远不要说永远!"* (19认同)
  • 我不认为_不使用标准库_本身就是一种美德,但这是一个很好的答案. (9认同)

pep*_*epr 34

我喜欢最简单的解决方案(包括效率).解决方案是否如此并不总是很清楚.无论如何,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]
Run Code Online (Sandbox Code Playgroud)

这就是range(5) + range(10, 20)Python 2.5中的确切做法 - 因为range()返回了一个列表.

在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
Run Code Online (Sandbox Code Playgroud)

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

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

#!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')
Run Code Online (Sandbox Code Playgroud)

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

itertools: 264.4522138986938 microsec/one execution
generator expression: 785.3081048010291 microsec/one execution
Run Code Online (Sandbox Code Playgroud)

......它快了大约3倍.


cs9*_*s95 27

蟒蛇> = 3.5

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

如果你需要一份清单,

[*range(2, 5), *range(3, 7)]
# [2, 3, 4, 3, 4, 5, 6]
Run Code Online (Sandbox Code Playgroud)

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

(*range(2, 5), *range(3, 7))
# (2, 3, 4, 3, 4, 5, 6)
Run Code Online (Sandbox Code Playgroud)

...或一组,

# note that this drops duplicates
{*range(2, 5), *range(3, 7)}
# {2, 3, 4, 5, 6}
Run Code Online (Sandbox Code Playgroud)

它也恰好比调用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)
Run Code Online (Sandbox Code Playgroud)

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

ranges = [range(2, 5), range(3, 7), ...]
flat = list(chain.from_iterable(ranges))
Run Code Online (Sandbox Code Playgroud)

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


Dar*_*ght 7

借助extend方法,我们可以连接两个列表.

>>> 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]
Run Code Online (Sandbox Code Playgroud)

  • 这适用于Python 2,OP使用Python 3. (2认同)