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中则是一个迭代器,它具有内存效率,但并不总是令人满意.
列表可以连接+,迭代器不能.
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)
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.chain的Lev 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
您可以在列表中使用可迭代解包(请参阅 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,解包概括尚未“泛化”到任意序列,因此您仍然需要自己解包各个范围。
借助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)
| 归档时间: |
|
| 查看次数: |
34069 次 |
| 最近记录: |