将多个 lambda 表达式组合成一行
Combining multiple lambda expressions into one line
一行实现,使用 lambda 表达式(map/filter/reduce),
获取不同类型列表的函数和 returns 具有这些键的字典:
{‘c’:,‘i’:,‘f’:,‘o’:}
'c' 将显示字符列表
'i' 整数列表
'f' 花车列表
'o' 任何其他类型的列表
例如列表:
myList = ['a', 2, 3, 's', 2.23]
输出将是:
{'c': ['a', 's'], 'i': [2, 3], 'f': [2.23], 'o': [ ]}
到目前为止,我制作了一种可行的方法,但我需要以某种方式更改它的一行代码:
def q1a(myList):
myDict = dict.fromkeys(('c', 'i', 'f', 'o'))
myDict['c'] = list(filter(lambda x: type(x) is str, myList))
myDict['i'] = list(filter(lambda x: type(x) is int, myList))
myDict['f'] = list(filter(lambda x: type(x) is float, myList))
myDict['o'] = list(filter(lambda x: type(x) is not float and type(x) is not int and type(x) is not str, myList))
return myDict
这解决了一次分配一个键的需要:
def q1a(myList):
return {
'c': list(filter(lambda x: type(x) is str, myList)),
'i': list(filter(lambda x: type(x) is int, myList)),
'f': list(filter(lambda x: type(x) is float, myList)),
'o': list(filter(lambda x: type(x) is not float and type(x) is not int and type(x) is not str, myList))
}
您可以使用列表理解并创建字典文字:
{
'c': [e for e in myList if type(e) is str],
'i': [e for e in myList if type(e) is int],
'f': [e for e in myList if type(e) is float],
'o': [e for e in myList if type(e) not in {float, int, str}]
}
作业似乎要求您对此采取函数式方法并创建单个操作。
一个选项是一个操作 dict 的 reduce。这在 python 中不像在其他语言中那样自然,因为大多数字典操作 return None。但是如果你尝试的话,你仍然可以以一种功能性的方式来做到这一点(它是为了(小)提高可读性而分解的单行代码):
from functools import reduce
l = ['a', 2, 3, 's', 2.23]
res = reduce(
lambda d, t: dict(d, **{t[1]: d[t[1]] + [t[0]]}),
map(lambda el: (el, {str: 'c', int: 'i', float: 'f'}.get(type(el), 'o')) , l),
dict.fromkeys('cifo', [])
)
print(res)
# {'c': ['a', 's'], 'i': [2, 3], 'f': [2.23], 'o': []}
这通过使用 map()
:
创建元组列表来实现
list(map(lambda el: (el, {str: 'c', int: 'i', float: 'f'}.get(type(el), 'o')) , l),)
# [('a', 'c'), (2, 'i'), (3, 'i'), ('s', 'c'), (2.23, 'f')]
然后更新 reduce 中的字典,该字典使用 dict.fromkeys('cifo', [])
创建的空列表进行初始化。
你可以使用下面丑陋的一行
out = dict(zip(['c','i','f','o'], map(list, (filter(lambda x:isinstance(x,str), lst), filter(lambda x:isinstance(x,int), lst), filter(lambda x:isinstance(x,float), lst), filter(lambda x: not isinstance(x,(str,float,int)), lst)))))
您还可以将 functools.reduce
与辅助函数一起使用(不完全是一个衬垫,但不需要多个 filter
,因此可以节省时间):
def add(d, x):
d[x[0]].append(x[1])
return d
from functools import reduce
out = reduce(add,
map(lambda x: (('c',x) if isinstance(x,str)
else (('i',x) if isinstance(x,int)
else (('f',x) if isinstance(x,float)
else ('o',x)))), lst),
{'c':[],'i':[],'f':[],'o':[]})
输出:
{'c': ['a', 's'], 'i': [2, 3], 'f': [2.23], 'o': []}
如果我在 Python 中写这个,我的第一选择是跳过函数式方法并使用无聊的 for
循环和 default
字典。
from collections import defaultdict
def q1a(myList):
d = defaultdict(list)
for v in myList:
if isinstance(v, str):
type_code = 'c'
elif isinstance(v, int):
type_code = 'i'
elif isinstnace(v, float):
type_code = 'f'
else:
type_code = 'o'
d[tc].append(v)
return d
但是,这表明使用 itertools.groupby
的解决方案。大 if
语句构成了一个像
这样的简单函数
def type_code(v):
if isinstance(v, str):
type_code = 'c'
elif isinstance(v, int):
type_code = 'i'
elif isinstnace(v, float):
type_code = 'f'
else:
type_code = 'o'
return type_code
可以写成适合在 lambda 表达式中使用的单个条件表达式:
lambda v: ('c' if isinstance(v, str) else
'i' if isinstance(v, int) else
'f' if isinstance(v, float) else
'o')
在下文中,为了便于阅读,我会将上述 lambda 表达式缩写为 tc
。
使用 itertools.groupby
,您可以使用指定每个元素属于哪个分区的函数对(排序的)列表进行分区。这样产生的分区适合在字典理解中使用。
from itertools import groupby
def q1a(myList):
return {k: list(vs) for k, vs in groupby(sorted(myList, key=tc), tc)}
一个小故障:
>>> q1a(['a', 2, 3, 's', 2.23])
{'c': ['a', 's'], 'f': [2.23], 'i': [2, 3]}
结果不包括不是由列表中的值生成的键。您必须将结果与包含所有键的预初始化 dict
合并。
def q1a(myList):
return ({'c': [], 'i': [], 'f': [], 'o': []}
| {k: list(vs) for k, vs in groupby(sorted(myList, key=tc), tc)})
我不使用 dict.fromKeys("cifo", [])
,因为这样每个键都默认引用 相同的 空列表,而不是每个键都有一个不同的空列表。
您可以使用双重间接将类型转换为字母并使用 setdefault 更新生成的字典:
def q1a(myList):
types = {str:'c', int:'i', float:'f'}
myDict = dict()
for x in myList:
myDict.setdefault(types.get(type(x),'o'),[]).append(x)
return myDict
myList = ['a', 2, 3, 's', 2.23]
print(q1a(myList))
{'c': ['a', 's'], 'i': [2, 3], 'f': [2.23]}
使用 defaultdict 可以稍微简化它:
from collections import defaultdict
def q1a(myList):
types = defaultdict(lambda:'o',{str:'c', int:'i', float:'f'})
myDict = defaultdict(list)
for x in myList:
myDict[types[type(x)]].append(x)
return dict(myDict)
一行实现,使用 lambda 表达式(map/filter/reduce), 获取不同类型列表的函数和 returns 具有这些键的字典: {‘c’:,‘i’:,‘f’:,‘o’:}
'c' 将显示字符列表 'i' 整数列表 'f' 花车列表 'o' 任何其他类型的列表
例如列表: myList = ['a', 2, 3, 's', 2.23]
输出将是: {'c': ['a', 's'], 'i': [2, 3], 'f': [2.23], 'o': [ ]}
到目前为止,我制作了一种可行的方法,但我需要以某种方式更改它的一行代码:
def q1a(myList):
myDict = dict.fromkeys(('c', 'i', 'f', 'o'))
myDict['c'] = list(filter(lambda x: type(x) is str, myList))
myDict['i'] = list(filter(lambda x: type(x) is int, myList))
myDict['f'] = list(filter(lambda x: type(x) is float, myList))
myDict['o'] = list(filter(lambda x: type(x) is not float and type(x) is not int and type(x) is not str, myList))
return myDict
这解决了一次分配一个键的需要:
def q1a(myList):
return {
'c': list(filter(lambda x: type(x) is str, myList)),
'i': list(filter(lambda x: type(x) is int, myList)),
'f': list(filter(lambda x: type(x) is float, myList)),
'o': list(filter(lambda x: type(x) is not float and type(x) is not int and type(x) is not str, myList))
}
您可以使用列表理解并创建字典文字:
{
'c': [e for e in myList if type(e) is str],
'i': [e for e in myList if type(e) is int],
'f': [e for e in myList if type(e) is float],
'o': [e for e in myList if type(e) not in {float, int, str}]
}
作业似乎要求您对此采取函数式方法并创建单个操作。
一个选项是一个操作 dict 的 reduce。这在 python 中不像在其他语言中那样自然,因为大多数字典操作 return None。但是如果你尝试的话,你仍然可以以一种功能性的方式来做到这一点(它是为了(小)提高可读性而分解的单行代码):
from functools import reduce
l = ['a', 2, 3, 's', 2.23]
res = reduce(
lambda d, t: dict(d, **{t[1]: d[t[1]] + [t[0]]}),
map(lambda el: (el, {str: 'c', int: 'i', float: 'f'}.get(type(el), 'o')) , l),
dict.fromkeys('cifo', [])
)
print(res)
# {'c': ['a', 's'], 'i': [2, 3], 'f': [2.23], 'o': []}
这通过使用 map()
:
list(map(lambda el: (el, {str: 'c', int: 'i', float: 'f'}.get(type(el), 'o')) , l),)
# [('a', 'c'), (2, 'i'), (3, 'i'), ('s', 'c'), (2.23, 'f')]
然后更新 reduce 中的字典,该字典使用 dict.fromkeys('cifo', [])
创建的空列表进行初始化。
你可以使用下面丑陋的一行
out = dict(zip(['c','i','f','o'], map(list, (filter(lambda x:isinstance(x,str), lst), filter(lambda x:isinstance(x,int), lst), filter(lambda x:isinstance(x,float), lst), filter(lambda x: not isinstance(x,(str,float,int)), lst)))))
您还可以将 functools.reduce
与辅助函数一起使用(不完全是一个衬垫,但不需要多个 filter
,因此可以节省时间):
def add(d, x):
d[x[0]].append(x[1])
return d
from functools import reduce
out = reduce(add,
map(lambda x: (('c',x) if isinstance(x,str)
else (('i',x) if isinstance(x,int)
else (('f',x) if isinstance(x,float)
else ('o',x)))), lst),
{'c':[],'i':[],'f':[],'o':[]})
输出:
{'c': ['a', 's'], 'i': [2, 3], 'f': [2.23], 'o': []}
如果我在 Python 中写这个,我的第一选择是跳过函数式方法并使用无聊的 for
循环和 default
字典。
from collections import defaultdict
def q1a(myList):
d = defaultdict(list)
for v in myList:
if isinstance(v, str):
type_code = 'c'
elif isinstance(v, int):
type_code = 'i'
elif isinstnace(v, float):
type_code = 'f'
else:
type_code = 'o'
d[tc].append(v)
return d
但是,这表明使用 itertools.groupby
的解决方案。大 if
语句构成了一个像
def type_code(v):
if isinstance(v, str):
type_code = 'c'
elif isinstance(v, int):
type_code = 'i'
elif isinstnace(v, float):
type_code = 'f'
else:
type_code = 'o'
return type_code
可以写成适合在 lambda 表达式中使用的单个条件表达式:
lambda v: ('c' if isinstance(v, str) else
'i' if isinstance(v, int) else
'f' if isinstance(v, float) else
'o')
在下文中,为了便于阅读,我会将上述 lambda 表达式缩写为 tc
。
使用 itertools.groupby
,您可以使用指定每个元素属于哪个分区的函数对(排序的)列表进行分区。这样产生的分区适合在字典理解中使用。
from itertools import groupby
def q1a(myList):
return {k: list(vs) for k, vs in groupby(sorted(myList, key=tc), tc)}
一个小故障:
>>> q1a(['a', 2, 3, 's', 2.23])
{'c': ['a', 's'], 'f': [2.23], 'i': [2, 3]}
结果不包括不是由列表中的值生成的键。您必须将结果与包含所有键的预初始化 dict
合并。
def q1a(myList):
return ({'c': [], 'i': [], 'f': [], 'o': []}
| {k: list(vs) for k, vs in groupby(sorted(myList, key=tc), tc)})
我不使用 dict.fromKeys("cifo", [])
,因为这样每个键都默认引用 相同的 空列表,而不是每个键都有一个不同的空列表。
您可以使用双重间接将类型转换为字母并使用 setdefault 更新生成的字典:
def q1a(myList):
types = {str:'c', int:'i', float:'f'}
myDict = dict()
for x in myList:
myDict.setdefault(types.get(type(x),'o'),[]).append(x)
return myDict
myList = ['a', 2, 3, 's', 2.23]
print(q1a(myList))
{'c': ['a', 's'], 'i': [2, 3], 'f': [2.23]}
使用 defaultdict 可以稍微简化它:
from collections import defaultdict
def q1a(myList):
types = defaultdict(lambda:'o',{str:'c', int:'i', float:'f'})
myDict = defaultdict(list)
for x in myList:
myDict[types[type(x)]].append(x)
return dict(myDict)