5

I have the following code lines:

records = []

for future in futures:
  records.extends(future.result())

each future returns a list.

How can I write the above code but in one liner?

records = [future.result() for future in futures]

would result in a list inside list.

I have millions of records, i would rather not flat it after creating lists inside list

Dejell
  • 13,947
  • 40
  • 146
  • 229
  • Have you tried `records.extends(future.result() for future in futures)`? – Akshat Mahajan Jun 08 '17 at 17:49
  • I just got this answer below - but this way I need to declare records = [] in another line. this will make it 2 lines – Dejell Jun 08 '17 at 17:49
  • @Dejell Don't assume there is always a reasonable one-liner for every loop. I find your original loop slightly clearer than the accepted oneliner (although I wouldn't object to it in a code review). – chepner Jun 08 '17 at 18:17
  • @Dejell I updated my answer, check it and see if it works for you, I made a little research and I will apreciate your feedback – developer_hatch Jun 08 '17 at 19:24

3 Answers3

9
records = [r for future in futures for r in future.result()]
Błotosmętek
  • 12,717
  • 19
  • 29
2

There are many ways to do this:

  1. Use itertools.chain:
    records = list(itertools.chain.from_iterable(future.result() for future in futures))
  2. Use the itertools consume recipe:
    records = collections.deque((records.extend(future.result()) for future in futures), maxlen=0)
  3. Use a throw-away list:
    [records.extend(future.result()) for future in futures]. records will now have all the required content, and you will have temporarily made a list of Nones

You could also do functools.reduce(operator.add, (future.result() for future in futures)), but that wouldn't scale very well

inspectorG4dget
  • 110,290
  • 27
  • 149
  • 241
  • regarding the third suggestion - I will need to declare records in another line – Dejell Jun 08 '17 at 17:50
  • 2
    Never a great fan of using a list comprehension for side effects. Just use a loop - `[print(x) for x in iterable]` - ugh! Vote for number 1. Doesn't number 2 just discard everything? – AChampion Jun 08 '17 at 17:55
  • @AChampion: you're right. I was just trying to cover all the bases. Thanks for the bugreport on #2. Fixed now – inspectorG4dget Jun 08 '17 at 18:05
  • @AChampion You were right about the comment in my answer, I edited it to not to make the same mistake again – developer_hatch Jun 08 '17 at 19:17
  • @inspectorG4dget Thanks a lot for sharing, that helped me a lot to make a better answer! plus one for ya – developer_hatch Jun 08 '17 at 19:38
1

I think this is what you are looking for

import functools
records = functools.reduce(lambda res, future: res + future.result()), futures, [])
developer_hatch
  • 15,898
  • 3
  • 42
  • 75