0

Sorry for the bad title, but I didn't know how to formulate it better ^^.

What I'm trying to do is iterate over a list of objects, and then iterate over a list that's a member of each object.


So something like this:

class FooObj:
    def __init__(self):
        self.list = [1, "Hello", 3.4] #some list thats unique for each object

objects = [...] # some list of FooObj's

for o in objects:
   for e in o.list:
        # Do something for each list element

That's the way I would do it 'traditionally'. I'm interested if there's a way to condensate the two for loops into one?

Thanks for your help ^^

Jakob Sachs
  • 669
  • 4
  • 24
  • Depends what you are trying to do. If you are retrieving a `list` of `list`, you can consider using `list comprehension`. But if you are actually performing certain actions on the sublists you might as well stick with this. Either way you will have to iterate through the list of objects and the attribute list. – r.ook Dec 03 '18 at 15:07
  • It depends what you are doing for each list element. It may be that having 2 `for` loops is the best way. You can combine both `for` loops using list comprehensions for example but that's only recommended if you are trying to build a list. – T Burgis Dec 03 '18 at 15:07
  • 1
    It would help clarify your question if you can illustrate an example of what you are trying to do with the `list`. There can be some perhaps dirtier methods to achieve it without even the double loop. – r.ook Dec 03 '18 at 15:09

2 Answers2

3

You can use itertools.chain.from_iterable if you really don't care from which FooObj the elements come:

from itertools import chain

for e in chain.from_iterable(o.list for o in objects):
    # Do something for each element
    print(e)

This has the advantage that it is a generator, so it does not create any (potentially big) intermediate list.

Graipher
  • 6,891
  • 27
  • 47
  • Thanks, also a solution, but @Akarius solution is shorter and doesn't require additional dependencies. Appreciate the help though! – Jakob Sachs Dec 03 '18 at 15:10
  • 2
    @JakobSachs: Note that the two answer give you different things. This gives you the elements of the lists, while the other answer only gives you the list objects over which you still need to iterate. Also `itertools` is in the standard library, so it should be always available. – Graipher Dec 03 '18 at 15:11
  • A thanks yes I can see the difference. Chance has it that in my application it doesn't make a difference. – Jakob Sachs Dec 03 '18 at 15:14
  • 2
    @JakobSachs: In that case why not do `for o in objects: print(o.list)` directly? No list comprehension needed. – Graipher Dec 03 '18 at 15:15
  • Because my "# Do something for each element" cant happen on a list but on each element – Jakob Sachs Dec 03 '18 at 15:18
1

If what you want is to iterate over the list for all objects at once, try this:

for i in [o.list for o in objects]:
    print(i)
Akarius
  • 388
  • 1
  • 7