One-liner to merge lists?

Chris Angelico rosuav at gmail.com
Sun Feb 27 11:28:23 EST 2022


On Mon, 28 Feb 2022 at 03:24, MRAB <python at mrabarnett.plus.com> wrote:
>
> On 2022-02-27 08:51, Barry Scott wrote:
> >
> >
> >> On 22 Feb 2022, at 09:30, Chris Angelico <rosuav at gmail.com> wrote:
> >>
> >> On Tue, 22 Feb 2022 at 20:24, Frank Millman <frank at chagford.com <mailto:frank at chagford.com>> wrote:
> >>>
> >>> Hi all
> >>>
> >>> I think this should be a simple one-liner, but I cannot figure it out.
> >>>
> >>> I have a dictionary with a number of keys, where each value is a single
> >>> list -
> >>>
> >>>>>> d = {1: ['aaa', 'bbb', 'ccc'], 2: ['fff', 'ggg']}
> >>>
> >>> I want to combine all values into a single list -
> >>>
> >>>>>> ans = ['aaa', 'bbb', 'ccc', 'fff', 'ggg']
> >>>
> >>> I can do this -
> >>>
> >>>>>> a = []
> >>>>>> for v in d.values():
> >>> ...   a.extend(v)
> >>> ...
> >>>>>> a
> >>> ['aaa', 'bbb', 'ccc', 'fff', 'ggg']
> >>>
> >>> I can also do this -
> >>>
> >>>>>> from itertools import chain
> >>>>>> a = list(chain(*d.values()))
> >>>>>> a
> >>> ['aaa', 'bbb', 'ccc', 'fff', 'ggg']
> >>>>>>
> >>>
> >>> Is there a simpler way?
> >>>
> >>
> >> itertools.chain is a good option, as it scales well to arbitrary
> >> numbers of lists (and you're guaranteed to iterate over them all just
> >> once as you construct the list). But if you know that the lists aren't
> >> too large or too numerous, here's another method that works:
> >>
> >>>>> sum(d.values(), [])
> >> ['aaa', 'bbb', 'ccc', 'fff', 'ggg']
> >>
> >> It's simply adding all the lists together, though you have to tell it
> >> that you don't want a numeric summation.
> >
> > If you code is performance sensitive do not use sum() as it creates lots of tmp list that are deleted.
> >
> > I have an outstanding ticket at work to replace all use of sum() on lists as when we profiled it
> > stands out as a slow operation. We have a lots of list of list that we need to flatten.
> >
> I think that 'sum' uses '__add__' but not '__iadd__'.
>
> If it copied the given value, if present, and then used '__iadd__', if
> present, wouldn't that speed it up?

It's hardly relevant. If you care about speed, use chain(), like
everyone's been saying all along :)

ChrisA


More information about the Python-list mailing list