
Currently, when the function for map() returns a list, the resulting object is an iterable of lists:
list(map(lambda x: [x, x], [1, 2, 3, 4])) [[1, 1], [2, 2], [3, 3], [4, 4]]
However, a function to convert each element to multiple elements, similar to flatMap (Java) or SelectMany (C#) does not exist, for doing the following:
list(mapmany(lambda x: [x, x], [1, 2, 3, 4])) [1, 1, 2, 2, 3, 3, 4, 4]
Proposal: new built-in method or standard library function to do mapmany. Sample use case: Library JSON data returns a list of authors, and each author has a list of books: { [ { 'author': 'name', 'books': ['book1', 'book2'] }, { 'author': 'name, 'books': ['book3', 'book4'] }, ... ] } allbooks = list(mapmany(lambda x: x['books'], json)) (First time posting - please redirect me to things I need to read if something's wrong with the format of this suggestion). Mark

On Aug 15, 2015 2:35 PM, "Petr Viktorin" <encukou@gmail.com> wrote:
On Sat, Aug 15, 2015 at 9:18 PM, Mark Tse <mark.tse@neverendingqs.com>
wrote:
I think this is something like toolz.itertoolz.mapcat: https://toolz.readthedocs.org/en/latest/api.html#toolz.itertoolz.mapcat

On 8/15/2015 12:18 PM, Mark Tse wrote:
In addition to the itertools solutions already posted, there's also a flatten function that'll do it: Python 2.7.6 (default, Mar 22 2014, 22:59:56) [GCC 4.8.2] on linux2 Type "help", "copyright", "credits" or "license" for more information.
Emile

On Sat, Aug 15, 2015, at 18:54, Wes Turner wrote:
Thanks! Hadn't been aware that there is a flatten() func in stdlib.
You should be aware that this will flatten _any_ list or tuple elements inside the elements, and it is gone in python 3. Also, it constructs the result as a list rather than an iterator, if that matters to you.

On Sat, Aug 15, 2015, at 22:02, Wes Turner wrote:
No, a string isn't a tuple or a list. The point is it will turn (1, 2, [3, (4, 5), 6, [7, 8, [9, 10]]]) into [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] So if you have [[(1, 2), (1, 2)], [(3, 4), (3, 4)]] it will become [1, 2, 1, 2, 3, 4, 3, 4] while the mapmany idea you originally discussed, and the solutions other people have given with itertools chain, would give [(1, 2), (1, 2), (3, 4), (3, 4)] Look for yourself, the source code is pretty understandable: def flatten(seq): l = [] for elt in seq: t = type(elt) if t is tuple or t is list: for elt2 in flatten(elt): l.append(elt2) else: l.append(elt) return l You can see it recursively calls flatten on every tuple or list element.

On Aug 15, 2015, at 19:15, Wes Turner <wes.turner@gmail.com> wrote:
Why would you expect a forward port of an undocumented function, especially one that trivial? Also, given that flatten doesn't do what you want here, and there's also a stdlib function (chain) that does what you want?

Wow...I was completely unaware of this! It's worth noting that *this is Python 2-only*. It will give an ImportError with Python 3. :( I really wish the stdlib had something like this, considering that I use it constantly. On Sat, Aug 15, 2015 at 5:17 PM, Emile van Sebille <emile@fenx.com> wrote:
-- Ryan [ERROR]: Your autotools build scripts are 200 lines longer than your program. Something’s wrong. http://kirbyfan64.github.io/

On Aug 15, 2015 6:52 PM, "Guido van Rossum" <guido@python.org> wrote:
object
* notes about flatten in toolz: https://github.com/pytoolz/toolz/issues/176 * flatten in fn.py: https://github.com/kachayev/fn.py#itertools-recipes

On 2015-08-18 00:58, Mark Tse wrote:
itertools.chain() expects the iterables as individual arguments, whereas itertools.chain.from_iterable() expects the iterables to be provided by a single argument that will yield those iterables itself; that means that you don't have to unpack them first as you're doing.

On Aug 15, 2015 2:35 PM, "Petr Viktorin" <encukou@gmail.com> wrote:
On Sat, Aug 15, 2015 at 9:18 PM, Mark Tse <mark.tse@neverendingqs.com>
wrote:
I think this is something like toolz.itertoolz.mapcat: https://toolz.readthedocs.org/en/latest/api.html#toolz.itertoolz.mapcat

On 8/15/2015 12:18 PM, Mark Tse wrote:
In addition to the itertools solutions already posted, there's also a flatten function that'll do it: Python 2.7.6 (default, Mar 22 2014, 22:59:56) [GCC 4.8.2] on linux2 Type "help", "copyright", "credits" or "license" for more information.
Emile

On Sat, Aug 15, 2015, at 18:54, Wes Turner wrote:
Thanks! Hadn't been aware that there is a flatten() func in stdlib.
You should be aware that this will flatten _any_ list or tuple elements inside the elements, and it is gone in python 3. Also, it constructs the result as a list rather than an iterator, if that matters to you.

On Sat, Aug 15, 2015, at 22:02, Wes Turner wrote:
No, a string isn't a tuple or a list. The point is it will turn (1, 2, [3, (4, 5), 6, [7, 8, [9, 10]]]) into [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] So if you have [[(1, 2), (1, 2)], [(3, 4), (3, 4)]] it will become [1, 2, 1, 2, 3, 4, 3, 4] while the mapmany idea you originally discussed, and the solutions other people have given with itertools chain, would give [(1, 2), (1, 2), (3, 4), (3, 4)] Look for yourself, the source code is pretty understandable: def flatten(seq): l = [] for elt in seq: t = type(elt) if t is tuple or t is list: for elt2 in flatten(elt): l.append(elt2) else: l.append(elt) return l You can see it recursively calls flatten on every tuple or list element.

On Aug 15, 2015, at 19:15, Wes Turner <wes.turner@gmail.com> wrote:
Why would you expect a forward port of an undocumented function, especially one that trivial? Also, given that flatten doesn't do what you want here, and there's also a stdlib function (chain) that does what you want?

Wow...I was completely unaware of this! It's worth noting that *this is Python 2-only*. It will give an ImportError with Python 3. :( I really wish the stdlib had something like this, considering that I use it constantly. On Sat, Aug 15, 2015 at 5:17 PM, Emile van Sebille <emile@fenx.com> wrote:
-- Ryan [ERROR]: Your autotools build scripts are 200 lines longer than your program. Something’s wrong. http://kirbyfan64.github.io/

On Aug 15, 2015 6:52 PM, "Guido van Rossum" <guido@python.org> wrote:
object
* notes about flatten in toolz: https://github.com/pytoolz/toolz/issues/176 * flatten in fn.py: https://github.com/kachayev/fn.py#itertools-recipes

On 2015-08-18 00:58, Mark Tse wrote:
itertools.chain() expects the iterables as individual arguments, whereas itertools.chain.from_iterable() expects the iterables to be provided by a single argument that will yield those iterables itself; that means that you don't have to unpack them first as you're doing.
participants (11)
-
Akira Li
-
Alexander Belopolsky
-
Andrew Barnert
-
Emile van Sebille
-
Guido van Rossum
-
Mark Tse
-
MRAB
-
Petr Viktorin
-
random832@fastmail.us
-
Ryan Gonzalez
-
Wes Turner