One-liner to merge lists?

Avi Gross avigross at verizon.net
Wed Feb 23 01:02:00 EST 2022


I had to think about it too, David.

Renaming it lets it make a bit more sense:

[item for sublist in d.values() for item in sublist]

This spells it out for me that you are taking one list within the main list at a time and then taking one item at a time from the list. Since the nesting is consistent in this case it makes sense.

Sadly, I could break it easily by just adding a non-list item like this:

d = {1: ['aaa', 'bbb', 'ccc'], 2: ['fff', 'ggg'], 3: 666}

And, of course, if you nest it any deeper, it is not completely flattened.

Chris makes the point that using the chain version may be better as it is compiled in C. Really? I would prefer a solution that even if slower, is more robust. Is there some function already written that will flatten what is given to it by checking the type of what is supplied, and based on the type, returning any simple objects like numbers or a character string, and converting many other composite things to something like a list and after popping off an entry, calling itself recursively on the rest until the list is empty? 

This would be a good start:

def flatten2list(object):
    gather = []
    for item in object:
        if isinstance(item, (list, tuple, set)):
            gather.extend(flatten2list(item))            
        else:
            gather.append(item)
    return gather

Of course I had to call the above as:

flatten2list(d.values())
['aaa', 'bbb', 'ccc', 'fff', 'ggg']

Here is a more complex version of the dictionary:

d = {1: ['aaa', 'bbb', 'ccc'], 2: [['fff', ['ggg']]], 3: 666, 4: set(["a", "e", "i", "o", "u"])}
d.values()
dict_values([['aaa', 'bbb', 'ccc'], [['fff', ['ggg']]], 666, {'e', 'u', 'a', 'o', 'i'}])

flatten2list(d.values())

['aaa', 'bbb', 'ccc', 'fff', 'ggg', 666, 'e', 'u', 'a', 'o', 'i']


The quest for a one-liner sometimes forgets that a typical function call is also a one-liner, with the work hidden elsewhere, often in a module written in python or mainly in C and so on. I suspect much more detailed functions like the above are available with a little search that handle more including just about any iterable that terminates.


-----Original Message-----
From: Dan Stromberg <drsalists at gmail.com>
To: David Raymond <David.Raymond at tomtom.com>
Cc: python-list at python.org <python-list at python.org>
Sent: Tue, Feb 22, 2022 11:02 pm
Subject: Re: One-liner to merge lists?


On Tue, Feb 22, 2022 at 7:46 AM David Raymond <David.Raymond at tomtom.com>
wrote:

> > Is there a simpler way?
>
> >>> d = {1: ['aaa', 'bbb', 'ccc'], 2: ['fff', 'ggg']}
> >>> [a for b in d.values() for a in b]
> ['aaa', 'bbb', 'ccc', 'fff', 'ggg']
> >>>
>

I like that way best.

But I'd still:
1) use a little more descriptive identifiers
2) put it in a function with a descriptive name
3) give the function a decent docstring

-- 
https://mail.python.org/mailman/listinfo/python-list



More information about the Python-list mailing list