Уведомления

Группа в Telegram: @pythonsu

#1 Июль 1, 2012 21:28:49

alekzp
Зарегистрирован: 2012-06-14
Сообщения: 13
Репутация: +  1  -
Профиль   Отправить e-mail  

Новечку нужна помощь, пара лёгких задачек))

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 чисел вошли, столько же должно и выйти.

Офлайн

#2 Июль 1, 2012 21:45:33

fata1ex
От:
Зарегистрирован: 2009-07-11
Сообщения: 732
Репутация: +  52  -
Профиль   Отправить e-mail  

Новечку нужна помощь, пара лёгких задачек))

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]



Отредактировано fata1ex (Июль 1, 2012 21:46:14)

Офлайн

#3 Июль 1, 2012 22:06:07

alekzp
Зарегистрирован: 2012-06-14
Сообщения: 13
Репутация: +  1  -
Профиль   Отправить e-mail  

Новечку нужна помощь, пара лёгких задачек))

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, большое спасибо за пример генератора списков. Лучше сразу привыкать к таким вещам.

Офлайн

#4 Июль 2, 2012 01:02:37

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 9855
Репутация: +  853  -
Профиль   Отправить e-mail  

Новечку нужна помощь, пара лёгких задачек))

>>> 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]
>>>



Офлайн

#5 Июль 2, 2012 01:07:05

fata1ex
От:
Зарегистрирован: 2009-07-11
Сообщения: 732
Репутация: +  52  -
Профиль   Отправить e-mail  

Новечку нужна помощь, пара лёгких задачек))

py.user.next, в задаче отображение из N чисел в элементы (массив), я просто привёл числовой ряд, чтобы не захламлять код.



Офлайн

#6 Июль 2, 2012 07:50:43

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 9855
Репутация: +  853  -
Профиль   Отправить e-mail  

Новечку нужна помощь, пара лёгких задачек))

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]
>>>



Отредактировано py.user.next (Июль 2, 2012 07:57:51)

Офлайн

#7 Июль 2, 2012 12:19:36

fata1ex
От:
Зарегистрирован: 2009-07-11
Сообщения: 732
Репутация: +  52  -
Профиль   Отправить e-mail  

Новечку нужна помощь, пара лёгких задачек))

Хм. Последний вариант оказался быстрее моего в два раза :)

Поэтому пришлось написать ещё один:

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 (Июль 2, 2012 12:53:32)

Офлайн

#8 Июль 2, 2012 13:17:32

fata1ex
От:
Зарегистрирован: 2009-07-11
Сообщения: 732
Репутация: +  52  -
Профиль   Отправить e-mail  

Новечку нужна помощь, пара лёгких задачек))

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
Всё. Теперь я могу спать спокойно.



Отредактировано fata1ex (Июль 2, 2012 13:43:19)

Офлайн

#9 Июль 3, 2012 01:43:29

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 9855
Репутация: +  853  -
Профиль   Отправить e-mail  

Новечку нужна помощь, пара лёгких задачек))

>>> 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]
>>>



Офлайн

#10 Июль 3, 2012 10:30:11

fata1ex
От:
Зарегистрирован: 2009-07-11
Сообщения: 732
Репутация: +  52  -
Профиль   Отправить e-mail  

Новечку нужна помощь, пара лёгких задачек))

py.user.next, это к чему?



Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version