Найти - Пользователи
Полная версия: Новечку нужна помощь, пара лёгких задачек))
Начало » Центр помощи » Новечку нужна помощь, пара лёгких задачек))
1 2 3
alekzp
fata1ex
>>> a = [1,2,3,4,5]
>>> b = [6,7,8,9,10]
>>> map(None, a, b)
[(1, 6), (2, 7), (3, 8), (4, 9), (5, 10)]
>>> zip(a, b)
[(1, 6), (2, 7), (3, 8), (4, 9), (5, 10)]

Не подходит. Во-первых, вручную писать списки — это всегда частный случай. Зачем оно нам? Во-вторых
>>> print(len(zip(a, b))) 
>>> 5
а это не правильно и противоречит закону сохранения массы если 10 чисел вошли, столько же должно и выйти.
fata1ex
alekzp, erm, я просто указал, что map(None, ..) ~ zip(…), поэтому аргумент насчет python 3 не работает. А вот законом сохранения я спорить не в праве :(

А вообще, прочитав условие, я бы написал так::
>>> [i - 1 if i % 2 else i + 1 for i in xrange(10)]
[1, 0, 3, 2, 5, 4, 7, 6, 9, 8]
alekzp
fata1ex
alekzp, erm, я просто указал, что map(None, ..) ~ zip(…), поэтому аргумент насчет python 3 не работает. А вот законом сохранения я спорить не в праве

А вообще, прочитав условие, я бы написал так::
>>> [i - 1 if i % 2 else i + 1 for i in xrange(10)]
[1, 0, 3, 2, 5, 4, 7, 6, 9, 8]

Супер. Только начинаю знакомиться с Python, большое спасибо за пример генератора списков. Лучше сразу привыкать к таким вещам.
py.user.next
>>> list(xrange(1, 9))
[1, 2, 3, 4, 5, 6, 7, 8]
>>> [i - 1 if i % 2 else i + 1 for i in xrange(1, 9)]
[0, 3, 2, 5, 4, 7, 6, 9]
>>>
fata1ex
py.user.next, в задаче отображение из N чисел в элементы (массив), я просто привёл числовой ряд, чтобы не захламлять код.
py.user.next
alekzp
Предлагаю просто проверять элемент на чётность:
в массиве могут быть любые числа

fata1ex
map(None, ..) ~ zip(…)
второй
>>> map(None, [1, 2, 3], [4, 5])
[(1, 4), (2, 5), (3, None)]
>>>

третий
>>> list(zip([1, 2, 3], [4, 5]))
[(1, 4), (2, 5)]
>>> 
>>> 
>>> import itertools
>>> list(itertools.zip_longest([1, 2, 3], [4, 5]))
[(1, 4), (2, 5), (3, None)]
>>>

тот пример переделанный
import itertools
 
a, result = range(5), []
for x in itertools.zip_longest(a[1::2], a[::2]):
    if x[0]:
        result += x
    else:
        result.append(x[1])
 
result

заменил на .extend()
>>> import itertools
>>> 
>>> a, result = range(5), []
>>> for x in itertools.zip_longest(a[1::2], a[::2]):
...     if x[0]:
...         result.extend(x)
...     else:
...         result.append(x[1])
... 
>>> result
[1, 0, 3, 2, 4]
>>>
fata1ex
Хм. Последний вариант оказался быстрее моего в два раза :)

Поэтому пришлось написать ещё один:
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%.
fata1ex
list(chain(*zip(a[1::2], a[::2]))) + ([a[-1]] if len(a) % 2 else [])
И даже это медленнее :o (~ 6%)

from itertools import chain
list(chain.from_iterable(zip(a[1::2], a[::2]))) + ([a[-1]] if len(a) % 2 else [])
3.0667548179626465
1.740900993347168
Всё. Теперь я могу спать спокойно.
py.user.next
>>> import itertools
>>> list(itertools.chain(zip(range(3), range(5))))
[(0, 0), (1, 1), (2, 2)]
>>> list(itertools.chain(*zip(range(3), range(5))))
[0, 0, 1, 1, 2, 2]
>>>
fata1ex
py.user.next, это к чему?
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB