viem77: (9May)
[personal profile] viem77
...сознаниестандартные функции.

Иногда бывает надо, чтоб функция, обрабатывающая серию значений, была универсальна, и понимала одновременно и список на входе одним аргументом и список аргументов и даже одиночный аргумент, списком не являющийся. Делается это достаточно просто:

def _convertargs(iter*args):
  if len(args):
    list = (iter,)+args
  else:
    if hasattr(iter,'__getitem__'):
      list = iter
    else:
      list = (iter,)
    return list










Соответственно если аргументов несколько - соединяем первый с остальными в список и работаем. Если аргумент один и является списком - все хорошо, работаем дальше. Если же аргумент один и он ни разу не список - не вопрос, мы его таковым сделаем и таки да, работаем дальше.

Но может случиться такая ситуация, при которой нам надо дополнить обработку списка аргументов стандартными функциями. Например, встроенные max() и min() выдадут нам ошибку, если мы им скормим max(0), например.

>>> max(0)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'int' object is not iterable





Хотя чисто логически никакой крамолы в этом нет. В таком случае мы переопределим функцию max(), чтоб преобразовать неперечислимый аргумент в список из одного элемента, а потом вызвать уже родной встроенный max().

import __builtin__

def max(iter*args):
  return __builtin__.max(_convertargs(iter*args))





Проверяем:

>>> max(0)
0



Может быть для кого-то это все боянъ и "спасибо, кэп", но мало ли :)

П.С. Под списком тут вполне себе понимаются все перечислимые (iterable) типы.

ЧЯДНТ?

Date: 2010-12-09 06:09 pm (UTC)
From: [identity profile] quallian-leion.livejournal.com
>>> def id(*args):
...     return args
... 
>>> print max(id(1,2,3))
3
>>> print max(id(1))
1

Re: ЧЯДНТ?

Date: 2010-12-09 06:13 pm (UTC)
From: [identity profile] quallian-leion.livejournal.com
хотя я кажется понял идею
max(id([1,2,3])) не работает

Re: ЧЯДНТ?

Date: 2010-12-09 06:39 pm (UTC)
From: [identity profile] viem77.livejournal.com
Да, id(1) вернет (1,) вместо 1, просто выводя через print, ты этого не видишь. А насчет "не работает" вдогонку к первому ответу:
>>> id([1,2,3])
([1, 2, 3],)

Чуешь разницу?

Re: ЧЯДНТ?

Date: 2010-12-09 06:36 pm (UTC)
From: [identity profile] viem77.livejournal.com
Родной max:
>>> def id(*args):
...   return args
...
>>> id(1)
(1,)
>>> id(1,2,3)
(1, 2, 3)
>>> max(id([1,2,3]))
[1, 2, 3]

С моими изменениями:
>>> max(id([1,2,3]))
[1, 2, 3]
>>> max(id(1,2,3))
3.0

Все правильно, [1,2,3], переданный через id() будет воспринят, как список из одного элемента, в котором суть список, кой сам себе максимум.

Re: ЧЯДНТ?

Date: 2010-12-09 06:54 pm (UTC)
From: [identity profile] quallian-leion.livejournal.com
как-то все же некрасиво выходит с двумя ифами
наверняка в питоне можно лаконичнее

Re: ЧЯДНТ?

Date: 2010-12-09 07:13 pm (UTC)
From: [identity profile] viem77.livejournal.com
Эээ, ну, например
def _convertargs(iter, *args):
  if len(args):
    list = (iter,)+args
  elif hasattr(iter,'__getitem__'):
    list = iter
  else:
    list = (iter,)
  return list

February 2013

S M T W T F S
     12
3456789
1011121314 1516
17181920212223
2425262728  

Style Credit

Expand Cut Tags

No cut tags
Page generated Jul. 26th, 2017 12:45 am
Powered by Dreamwidth Studios