Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Python Higher Order Functions to Manipulate Lists

I've made this list; each item is a string that contains commas (in some cases) and colon (always):

dinner = [
    'cake,peas,cheese : No',
    'duck,broccoli,onions : Maybe',
    'motor oil : Definitely Not',
    'pizza : Damn Right',
    'ice cream : Maybe',
    'bologna : No',
    'potatoes,bacon,carrots,water: Yes',
    'rats,hats : Definitely Not',
    'seltzer : Yes',
    'sleeping,whining,spitting : No Way',
    'marmalade : No'
]

I would like to create a new list from the one above as follows:

['cake : No',
 'peas : No',
 'cheese : No',
 'duck : Maybe',
 'broccoli : Maybe',
 'onions : Maybe',
 'motor oil : Definitely Not',
 'pizza : Damn Right',
 'ice cream : Maybe',
 'bologna : No',
 'potatoes : Yes',
 'bacon : Yes',
 'carrots : Yes',
 'water : Yes',
 'rats : Definitely Not',
 'hats : Definitely Not',
 'seltzer : Yes',
 'sleeping : No Way',
 'whining : No Way',
 'spitting : No Way',
 'marmalade : No']

But I'd like to know if/ how it's possible to do so in a line or two of efficient code employing primarily Python's higher order functions. I've been attempting it:

reduce(lambda x,y: x + y, (map(lambda x: x.split(':')[0].strip().split(','), dinner)))

...produces this:

['cake',
 'peas',
 'cheese',
 'duck',
 'broccoli',
 'onions',
 'motor oil',
 'pizza',
 'ice cream',
 'bologna',
 'potatoes',
 'bacon',
 'carrots',
 'water',
 'rats',
 'hats',
 'seltzer',
 'sleeping',
 'whining',
 'spitting',
 'marmalade']

...but I'm struggling with appending the piece of each string after the colon back onto each item.

like image 897
dstar Avatar asked Feb 21 '16 00:02

dstar


People also ask

What are the different types of higher order functions in Python?

In this article, we want to focus our discussion on three commonly used higher-order functions, namely map (), filter (), and reduce (). The first function that we’re discussing is the map () function, which has the following general format: map (mapping_function, *iterables).

How do you pass a method to a higher order function?

You can pass a method to a higher order function just like you would any function, you just have to pass it as object.method:

How do you map a list in Python?

The map () function returns a map object, which is not a list object. We use the string’s built-in function upper as the mapping function. We use the list () constructor to create a list from the map object. In addition to the use of the built-in function, we can declare a function ourselves as the mapping function.

What are higher order functions in C++?

Higher-order functions are functions that take a function as a parameter and/or return a function as an output. A few useful higher-order functions are map (), filter (), and reduce (). map () and filter () are built-in functions, whereas reduce () is contained in functools () module.


1 Answers

I would create a dict using, zip, map and itertools.repeat:

from itertools import repeat


data = ({k.strip(): v.strip() for _k, _v in map(lambda x: x.split(":"), dinner)
     for k, v in zip(_k.split(","), repeat(_v))})

from pprint import pprint as pp

pp(data)

Output:

{'bacon': 'Yes',
 'bologna': 'No',
 'broccoli': 'Maybe',
 'cake': 'No',
 'carrots': 'Yes',
 'cheese': 'No',
 'duck': 'Maybe',
 'hats': 'Definitely Not',
 'ice cream': 'Maybe',
 'marmalade': 'No',
 'motor oil': 'Definitely Not',
 'onions': 'Maybe',
 'peas': 'No',
 'pizza': 'Damn Right',
 'potatoes': 'Yes',
 'rats': 'Definitely Not',
 'seltzer': 'Yes',
 'sleeping': 'No Way',
 'spitting': 'No Way',
 'water': 'Yes',
 'whining': 'No Way'}

Or using the dict constructor:

from itertools import repeat

data = dict(map(str.strip, t) for _k, _v in map(lambda x: x.split(":"), dinner)
            for t in zip(_k.split(","), repeat(_v)))

from pprint import pprint as pp

pp(data)

If you really want a list of strings, we can do something similar using itertools.chain and joining the substrings:

from itertools import repeat, chain

data = chain.from_iterable(map(":".join, zip(_k.split(","), repeat(_v))) 
                           for _k, _v in map(lambda x: x.split(":"), dinner))


from pprint import pprint as pp

pp(list(data))

Output:

['cake: No',
 'peas: No',
 'cheese : No',
 'duck: Maybe',
 'broccoli: Maybe',
 'onions : Maybe',
 'motor oil : Definitely Not',
 'pizza : Damn Right',
 'ice cream : Maybe',
 'bologna : No',
 'potatoes: Yes',
 'bacon: Yes',
 'carrots: Yes',
 'water: Yes',
 'rats: Definitely Not',
 'hats : Definitely Not',
 'seltzer : Yes',
 'sleeping: No Way',
 'whining: No Way',
 'spitting : No Way',
 'marmalade : No']
like image 122
Padraic Cunningham Avatar answered Sep 30 '22 09:09

Padraic Cunningham