Re: One-liner to merge lists?

2022-02-27 Thread Peter Otten

On 27/02/2022 17:28, Chris Angelico wrote:

On Mon, 28 Feb 2022 at 03:24, MRAB  wrote:


On 2022-02-27 08:51, Barry Scott wrote:




On 22 Feb 2022, at 09:30, Chris Angelico  wrote:

On Tue, 22 Feb 2022 at 20:24, Frank Millman mailto:fr...@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 :)


Not everyone. I believe (*) that __iadd__ is faster, and again, you can
spell it

functools.reduce(operator.iconcat, list_of_lists, [])

(*) Actual measurements left as an exercise ;)

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


Re: One-liner to merge lists?

2022-02-27 Thread Chris Angelico
On Mon, 28 Feb 2022 at 03:24, MRAB  wrote:
>
> On 2022-02-27 08:51, Barry Scott wrote:
> >
> >
> >> On 22 Feb 2022, at 09:30, Chris Angelico  wrote:
> >>
> >> On Tue, 22 Feb 2022 at 20:24, Frank Millman  >> > 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
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: One-liner to merge lists?

2022-02-27 Thread MRAB

On 2022-02-27 08:51, Barry Scott wrote:




On 22 Feb 2022, at 09:30, Chris Angelico  wrote:

On Tue, 22 Feb 2022 at 20:24, Frank Millman mailto:fr...@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?

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


Re: One-liner to merge lists?

2022-02-27 Thread Barry Scott



> On 22 Feb 2022, at 09:30, Chris Angelico  wrote:
> 
> On Tue, 22 Feb 2022 at 20:24, Frank Millman  > 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.

Barry


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


Re: One-liner to merge lists?

2022-02-26 Thread Chris Angelico
On Sun, 27 Feb 2022 at 16:35, Dan Stromberg  wrote:
>
>
> On Fri, Feb 25, 2022 at 3:15 PM Chris Angelico  wrote:
>>
>> But ultimately, that's still the same as sum(), and it's no more
>> readable than chain(), so I'd still be inclined to go with chain and
>> then wrap it in a function if you need the clarity.
>
>
> "Need" the clarity?  Please tell me you don't think clarity is for the feeble 
> minded.
>

It's more about whether you consider that list(chain(...)) is a clear
and readable idiom, or you prefer to give a name to it. Not every
two-operation action needs its own name.

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


Re: One-liner to merge lists?

2022-02-26 Thread Dan Stromberg
On Fri, Feb 25, 2022 at 3:15 PM Chris Angelico  wrote:

> But ultimately, that's still the same as sum(), and it's no more
> readable than chain(), so I'd still be inclined to go with chain and
> then wrap it in a function if you need the clarity.
>

"Need" the clarity?  Please tell me you don't think clarity is for the
feeble minded.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: One-liner to merge lists?

2022-02-25 Thread Chris Angelico
On Sat, 26 Feb 2022 at 10:05, Albert-Jan Roskam  wrote:
>Was also thinking about reduce, though this one uses a dunder method:
>from functools import reduce
>d = {1: ['aaa', 'bbb', 'ccc'], 2: ['fff', 'ggg']}
>print(reduce(list.__add__, list(d.values(

If you don't want to use the dunder, just use the operator module:

reduce(operator.add, d.values())

But ultimately, that's still the same as sum(), and it's no more
readable than chain(), so I'd still be inclined to go with chain and
then wrap it in a function if you need the clarity.

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


Re: One-liner to merge lists?

2022-02-25 Thread Albert-Jan Roskam
 If you don't like the idea of 'adding' strings you can 'concat'enate:

 >>> items = [[1,2,3], [4,5], [6]]
 >>> functools.reduce(operator.concat, items)
 [1, 2, 3, 4, 5, 6]
 >>> functools.reduce(operator.iconcat, items, [])
 [1, 2, 3, 4, 5, 6]

 The latter is the functional way to spell your for... extend() loop.
 Don't forget to provide the initial value in that case lest you modify
 the input:

 >> functools.reduce(operator.iconcat, items)  # wrong
 [1, 2, 3, 4, 5, 6]
 >>> items
 [[1, 2, 3, 4, 5, 6], [4, 5], [6]]  # oops

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

   
   Was also thinking about reduce, though this one uses a dunder method:
   from functools import reduce
   d = {1: ['aaa', 'bbb', 'ccc'], 2: ['fff', 'ggg']}
   print(reduce(list.__add__, list(d.values(
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: One-liner to merge lists?

2022-02-23 Thread Peter Otten

On 22/02/2022 10:44, Frank Millman wrote:

On 2022-02-22 11:30 AM, Chris Angelico wrote:

On Tue, 22 Feb 2022 at 20:24, Frank Millman  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.



Thanks, that is neat.

However, I did see this -

 >>> help(sum)
Help on built-in function sum in module builtins:

sum(iterable, /, start=0)
     Return the sum of a 'start' value (default: 0) plus an iterable of
numbers

     When the iterable is empty, return the start value.
     This function is intended specifically for use with numeric values
and may reject non-numeric types.
 >>>

So it seems that it is not recommended.


If you don't like the idea of 'adding' strings you can 'concat'enate:

>>> items = [[1,2,3], [4,5], [6]]
>>> functools.reduce(operator.concat, items)
[1, 2, 3, 4, 5, 6]
>>> functools.reduce(operator.iconcat, items, [])
[1, 2, 3, 4, 5, 6]

The latter is the functional way to spell your for... extend() loop.
Don't forget to provide the initial value in that case lest you modify
the input:

>> functools.reduce(operator.iconcat, items)  # wrong
[1, 2, 3, 4, 5, 6]
>>> items
[[1, 2, 3, 4, 5, 6], [4, 5], [6]]  # oops


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


Re: One-liner to merge lists?

2022-02-22 Thread Frank Millman

On 2022-02-22 5:45 PM, David Raymond 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']






Now that's what I was looking for.

I am not saying that I will use it, but as an academic exercise I felt 
sure that there had to be a one-liner in pure python.


I had forgotten about nested comprehensions. Thanks for the reminder.

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


Re: One-liner to merge lists?

2022-02-22 Thread Avi Gross via Python-list
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 
To: David Raymond 
Cc: python-list@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 
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

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


Re: One-liner to merge lists?

2022-02-22 Thread Chris Angelico
On Wed, 23 Feb 2022 at 15:04, Dan Stromberg  wrote:
>
> On Tue, Feb 22, 2022 at 7:46 AM David Raymond 
> 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

If you're going to do that, then you may as well use list(chain()) and
let the work be done in C.

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


Re: One-liner to merge lists?

2022-02-22 Thread Dan Stromberg
On Tue, Feb 22, 2022 at 7:46 AM David Raymond 
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


Re: One-liner to merge lists?

2022-02-22 Thread Avi Gross via Python-list
Frank,

Given this kind of data: d = {1: ['aaa', 'bbb', 'ccc'], 2: ['fff', 'ggg']}

You seem focused on a one-liner, however ridiculous or inefficient. Does this 
count as a somewhat weird one liner?

comb = [];   _ = [comb.append(v) for v in d.values()]

If you run the code and ignore the returned result, the value in comb is:

print(comb)

[['aaa', 'bbb', 'ccc'], ['fff', 'ggg']]

As discussed the other day here, this is an example of a variant on the 
anonymous function discussion as what is wanted is a side effect. I could omit 
assigning the result to anything and run this code after the previous like this:

[comb.append(v) for v in d.values()]
[None, None]
comb
[['aaa', 'bbb', 'ccc'], ['fff', 'ggg'], ['aaa', 'bbb', 'ccc'], ['fff', 'ggg']]

As shown the list comprehension itself is not returning anything of value and 
need not be assigned to anything. But it then generally is set to autoprint and 
that can be supressed by assigning the value to _ or anything you can ignore.

I am NOT saying this is a good way but that it is sort of a one-liner. There 
are good reasons I do not see people doing things this way!

-Original Message-
From: Frank Millman 
To: python-list@python.org
Sent: Tue, Feb 22, 2022 4:19 am
Subject: One-liner to merge lists?


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?



Thanks



Frank Millman





-- 

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

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


RE: One-liner to merge lists?

2022-02-22 Thread David Raymond
> 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']
>>>

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


Re: One-liner to merge lists?

2022-02-22 Thread Chris Angelico
On Tue, 22 Feb 2022 at 20:46, Frank Millman  wrote:
>
> On 2022-02-22 11:30 AM, Chris Angelico wrote:
> > On Tue, 22 Feb 2022 at 20:24, Frank Millman  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.
> >
>
> Thanks, that is neat.
>
> However, I did see this -
>
>  >>> help(sum)
> Help on built-in function sum in module builtins:
>
> sum(iterable, /, start=0)
>  Return the sum of a 'start' value (default: 0) plus an iterable of
> numbers
>
>  When the iterable is empty, return the start value.
>  This function is intended specifically for use with numeric values
> and may reject non-numeric types.
>  >>>
>
> So it seems that it is not recommended.
>
> I think I will stick with itertools.chain.
>

Yup, itertools.chain is definitely the recommended way to do things.
It's short, efficient, and only slightly unclear. If the clarity is a
problem, you can always wrap it into a function:

def sum_lists(iterable):
return list(chain.from_iterable(iterable))


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


Re: One-liner to merge lists?

2022-02-22 Thread Frank Millman

On 2022-02-22 11:30 AM, Chris Angelico wrote:

On Tue, 22 Feb 2022 at 20:24, Frank Millman  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.



Thanks, that is neat.

However, I did see this -

>>> help(sum)
Help on built-in function sum in module builtins:

sum(iterable, /, start=0)
Return the sum of a 'start' value (default: 0) plus an iterable of 
numbers


When the iterable is empty, return the start value.
This function is intended specifically for use with numeric values
and may reject non-numeric types.
>>>

So it seems that it is not recommended.

I think I will stick with itertools.chain.

Frank

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


Re: One-liner to merge lists?

2022-02-22 Thread Chris Angelico
On Tue, 22 Feb 2022 at 20:24, Frank Millman  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.

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