Хм. Последний вариант оказался быстрее моего в два раза :)
Поэтому пришлось написать ещё один:
def bar(a):
for i in range(len(a) // 2):
yield a[2 * i + 1]
yield a[2 * i]
if len(a) % 2:
yield a[-1]
И тут выяснилось:
import itertools
def foo(a):
result = []
for x in itertools.zip_longest(a[1::2], a[::2]):
if x[0]:
result.extend(x)
else:
result.append(x[1])
return result
def bar(a):
for i in range(len(a) // 2):
yield a[2 * i + 1]
yield a[2 * i]
if len(a) % 2:
yield a[-1]
a = list(range(10)) * 1000
b = list(range(11)) * 1001
assert len(list(bar(a))) == len(a)
assert len(list(bar(b))) == len(b)
assert len(foo(a)) == len(a)
assert len(foo(b)) == len(b)
[13:14] home:~/dev python3.2 t.py
Traceback (most recent call last):
File "t.py", line 32, in <module>
assert len(foo(b)) == len(b)
AssertionError
Результаты timeit:
a = list(range(10)) * 1000000
import builtins
builtins.__dict__.update(locals())
print(timeit.Timer('foo(a)').timeit(1))
print(timeit.Timer('bar(a)').timeit(1))
3.176952838897705
1.3113021850585938e-05
print(timeit.Timer('foo(a)').timeit(1))
print(timeit.Timer('list(bar(a))').timeit(1))
0.32659008026123047
0.5073978519439697
:(
def bar(a):
res = []
for i in range(0, len(a) - 1, 2):
res.extend((a[i + 1], a[i]))
if len(a) % 2:
res.append(a[-1])
return res
Показывает результат в 1.4 раза хуже :)
def bar(a):
for i in range(0, len(a) - 1, 2):
yield a[i + 1]
yield a[i]
if len(a) % 2:
yield a[-1]
Логичное улучшение всё равно уступает из-за приведения типов :( Примерно на 30%.