使用Python高阶函数来操作列表

时间:2016-02-21 00:24:42

标签: python lambda reduce

我已经列出了这个名单;每个项目都是一个包含逗号(在某些情况下)和冒号(总是)的字符串:

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'
]

我想从上面创建一个新列表,如下所示:

['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']

但是我想知道是否/如何在一行或两行主要使用Python的高阶函数的情况下这样做。我一直在尝试:

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

...产生这个:

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

...但是我正在努力将结肠后的每个字符串附加到每个项目上。

4 个答案:

答案 0 :(得分:8)

我会使用zipmapitertools.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)

输出:

{'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'}

或者使用dict构造函数:

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)

如果你真的想要一个字符串列表,我们可以使用itertools.chain做类似的事情并加入子字符串:

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))

输出:

['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']

答案 1 :(得分:3)

假设你真的需要它作为字符串列表与字典,这看起来像一个更好的数据结构。

通过简化使用理解,您可以这样做:

>>> [[x+':'+y for x in i.split(',')]
...  for i, y in map(lambda l: map(str.strip, l.split(':')), dinner)]
[['cake:No', 'peas:No', 'cheese:No'],
 ['duck:Maybe', 'broccoli:Maybe', 'onions:Maybe'],
 ['motor oil:Definitely Not'],
 ...
 ['marmalade:No']]

现在只需add列表:

>>> from operator import add
>>> reduce(add, ([x+':'+y for x in i.split(',')]
...              for i, y in map(lambda l: map(str.strip, l.split(':')), dinner)), [])
['cake:No',
 'peas:No',
 'cheese:No',
 'duck:Maybe',
 ...
 'marmalade:No']

或者只是压扁列表:

>>> [a for i, y in map(lambda l: map(str.strip, l.split(':')), dinner) 
...  for a in (x+':'+y for x in i.split(','))]
['cake:No',
 'peas:No',
 'cheese:No',
 'duck:Maybe',
 ...
 'marmalade:No']

答案 2 :(得分:1)

这可能有效:

def processList (aList):
    finalList = []
    for aListEntry in aList:
        aListEntry_entries = aListEntry.split(':')
        aListEntry_list = aListEntry_entries[0].split(',')
        for aListEntry_list_entry in aListEntry_list:
            finalList.append(aListEntry_list_entry.strip() + ' : ' + aListEntry_entries[1].strip())
    return finalList

答案 3 :(得分:1)

列表推导在Python中是首选(检查例如this),因为更好的易读性(至少对某些人而言)。

代码演示了两种类型的列表推导嵌套,第一种是基本链接操作,另一种是从两个嵌套循环中生成一个列表。

如果您通过在carrots, water之后添加一个空格来使数据更加一致,则可以删除两个.strip()次呼叫;)

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'
]

prefs = [(pref, items.split(',')) for items, pref in [it.split(" : ") for it in dinner]]
[" : ".join([item, pref]) for pref, items in prefs for item in items]