1

I've written some code like so which works fine and does what I want:

#!/usr/bin/env python3

myList = [[0], [1, 2], {'val': [3, 4, 5]}, [6]]

flat1 = []
for sublist in myList:
    if type(sublist) is list:
        for item in sublist:
            flat1.append(item)
    else:
        for item in sublist['val']:
            flat1.append(item)

print(flat1)

So it's a twist on the standard nested list flattening. The twist is that some nested items are not actually lists, but rather dictionaries with a 'val' (and we want the items in the 'val' list in those cases).

I'm trying to make it into a list comprehension. Here is what I've tried:

flat2 = [item for sublist in myList for item in sublist if type(sublist) is list else for item in sublist['val']]
print(flat2)

I get the following error with a caret pointing to the 'else'.

SyntaxError: invalid syntax

And yes what I've written into the list comprehension seems like nonsense and no doubt the compiler has no idea what I'm trying to do.

Is it possible to do what I'm trying to do with a list comprehension?

2 Answers 2

5
[item
    for sublist in myList
    for item in (sublist if type(sublist) is list else sublist['val'])
]
Sign up to request clarification or add additional context in comments.

Comments

1

First off, I recommend against this approach. Why do you want to take what is already pretty readable and condense it so that it's unreadable?

flattened =  [i for iterable in 
              (j if type(j) is list else j["val"] for j in myList)
              for i in iterable]

Update after reading comment

One nice thing to do is to break out the list comprehension into two steps:

iterables = (j if type(j) is list else j["val"] for j in myList)
flattened = [i for iterable in iterables for i in iterable] 

This is more readable -- and no less computationally efficient. Note the use of parentheses in iterables -- which makes it a generator that is lazily evaluated. That way, if myList is really long, you're still only reading through it once and you don't have to wait to read all the way through before proceeding.

2 Comments

I thought this would be a good opportunity to learn a harder list comprehension. It was already a list comprehension prior to me adding the dicts so naturally I wanted to just upgrade that line (the longer code is just me working this out). I find list comprehensions difficult to read in general, so this isn't that much different. I'm not concerned about readability on this one as shocking as that may be to admit, I have a comment there saying it flattens the list anyway. Also, I prefer the amount of code to be closer to the effort it takes me to look at the list and see 0,1,2,3,4,5,6.
Other modern languages allow these constructs much more easily than python. It is a good question along the lines of : how can we get closer to what we're used to elsewhere that has better functionals support?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.