Есть ли способ, которым я могу превратить это в понимание списка - PullRequest
1 голос
/ 24 января 2012

Я часто обнаруживаю, что делаю неэффективные циклы как таковые:

def __add__(self, other):
    dimensions = []
    for i in range(max(self.numberOfDimensions, other.numberOfDimensions)):
        a = None    
        if i < self.numberOfDimensions:
            a = self[i]     
        b = None    
        if i < other.numberOfDimensions:
            b = other[i]    

        # Doesn't actually do the right thing here.
        dimensions.append(sum(map(lambda x: ((x is None) and 1 or 2) - 1, (a, b))))

    return self.__class__(dimensions)

Расчет прост, он просто обрабатывает типы операторов if, которые меня получают.Кстати, это подкласс кортежа, в котором оператор добавления добавляет аналогичные значения индекса, например, (1, 2, 3) + (4, 5, 6, 7) == (5, 7, 9, 7).Я бы подумал, что filter() поможет мне в этом, но я не уверен, как бы это реализовать.

РЕДАКТИРОВАТЬ: Это для Python 3.

Ответы [ 5 ]

6 голосов
/ 24 января 2012

Я не уверен, что полностью понял, но думаю, что stdlib - ваш друг:

from itertools import izip_longest
dimensions = []
for a, b in izip_longest(self, other, fillvalue=0):
    dimensions.append(a + b)

Не думаю, что понимание списка было бы очень чистым.

2 голосов
/ 24 января 2012

Самый краткий способ сделать это -

map(sum, itertools.izip_longest(self, other, fillvalue=0))

или

itertools.starmap(operator.add, 
                  itertools.izip_longest(self, other, fillvalue=0))

Это то, что, как я предполагаю, должен делать ваш оригинальный код.Если вы используете Python 3, преобразуйте результат в кортеж или список, или что вы хотите.

2 голосов
/ 24 января 2012

Вот тривиальный способ использовать списки, хотя это довольно уродливо ИМХО.

dimensions = [
  sum(map(lambda x: ((x is None) and 1 or 2) - 1, (
    self[i] if i<self.numberOfDimensions else None,
    other[i] if i<other.numberOfDimensions else None
  )))

  for i in range(max(self.numberOfDimensions, other.numberOfDimensions))  
]
1 голос
/ 24 января 2012

как насчет этого, хотя и не проверено:

dimensions = [sum(map(lambda x: ((x is None) and 1 or 2) - 1, (self[i] if i < self.numberOfDimensions else None, other[i] if i < other.numberOfDimensions else None))) for i in range(max(self.numberOfDimensions, other.numberOfDimensions))]
0 голосов
/ 24 января 2012

Я думаю, что вам нужна недостающая часть:

(a,b) = (self[i] if i < self.numberOfDimensions else None, other[i] if i < other.numberOfDimensions else None)

Конечно, я не уверен, что одно выражение будет более читабельным.Возможно, вам лучше использовать какую-то карту, чтобы сначала сгенерировать (a,b) s.

...