1

How would I write the following more concisely?

    genres = ','.join([item for item in list((sheet.cell(n,18).value, 
                      sheet.cell(n,19).value, sheet.cell(n,20).value)) if item])
David542
  • 104,438
  • 178
  • 489
  • 842
  • Btw, the `list()` call is useless, since you can use a generator expression. See @Julian answer. – rubik Aug 19 '12 at 19:31

2 Answers2

6
','.join(filter(None, (sheet.cell(n, i).value for i in (18, 19, 20))))

The (sheet.cell(n, i).value for i in (18, 19, 20)) is a generator expression replacing the list(…) part. You may replace the tuple (18, 19, 20) with a range or something else.

The filter(None, iterable) is equivalent to (x for x in iterable if x). (In Python 2.x you may want to use itertools.ifilter instead.)


Note also that, you can create a list using

[sheet.cell(n,18).value, sheet.cell(n,19).value, sheet.cell(n,20).value]

instead of the longer list((sheet.cell(n,18).value, …)).

Community
  • 1
  • 1
kennytm
  • 510,854
  • 105
  • 1,084
  • 1,005
  • Wouldn't [`itertools.ifilter`](http://docs.python.org/library/itertools.html#itertools.ifilter) be more accurate equivalent of the generator expression? (in Python 2.x) – Imran Aug 19 '12 at 19:56
  • @Imran: Right. And in Python 3 `filter` is enough. – kennytm Aug 19 '12 at 20:06
5

On two lines. Readability trumps conciseness.

Your list comprehension is also unnecessary, a genexp will do fine.

genre_values = (sheet.cell(n, i).value for i in xrange(18, 21))
genres = ", ".join(value for value in genre_cells if value)
Julian
  • 3,375
  • 16
  • 27