简体   繁体   中英

Is there any way that I can turn this into a list comprehension

I often find myself doing inefficient loops as such:

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)

The calculation is simple, it's just handling the if statements types that's getting me. By the way, this is a subclass of tuple in which the add operator adds similar index's values like so (1, 2, 3) + (4, 5, 6, 7) == (5, 7, 9, 7) . I would think that filter() would help me out on this but I'm not sure how I'd implement it.

EDIT: This is for Python 3.

I'm not sure if I'm totally getting it, but I think the stdlib is your friend:

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

I don't think a list comprehension would be very clean.

Here's the trivial way to use list comprehension, though it's pretty ugly IMHO.

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

The most concise way to do this is

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

or

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

This does what I guess your original code is supposed to do. If you are using Python 3, convert the result to a tuple or list or whatever you want it to be.

怎么样,尽管未经测试:

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

I think the missing piece you need is:

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

Of course, I'm not convinced that a single expression will be more readable. You might be better off using some kind of map to generate the (a,b) s first.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM