Mat*_*ieu 2 python list-comprehension
我正在寻找一种简洁实用的样式方法,将函数应用于元组的一个元素并返回Python中的新元组.
例如,对于以下输入:
inp = ("hello", "my", "friend")
Run Code Online (Sandbox Code Playgroud)
我希望能够得到以下输出:
out = ("hello", "MY", "friend")
Run Code Online (Sandbox Code Playgroud)
我想出了两个我不满意的解决方案.
一个使用高阶函数.
def apply_at(arr, func, i):
return arr[0:i] + [func(arr[i])] + arr[i+1:]
apply_at(inp, lambda x: x.upper(), 1)
Run Code Online (Sandbox Code Playgroud)
一个使用列表推导(这个假定元组的长度是已知的).
[(a,b.upper(),c) for a,b,c in [inp]][0]
Run Code Online (Sandbox Code Playgroud)
有没有更好的办法?谢谢!
这是一个适用于任何iterable并返回生成器的版本:
>>> inp = ("hello", "my", "friend")
>>> def apply_nth(fn, n, iterable):
... return (fn(x) if i==n else x for (i,x) in enumerate(iterable))
...
>>> tuple(apply_nth(str.upper, 1, inp))
('hello', 'MY', 'friend')
Run Code Online (Sandbox Code Playgroud)
你可以扩展它,这样你可以给它一个位置列表,而不是一个位置:
>>> def apply_at(fn, pos_lst, iterable):
... pos_lst = set(pos_lst)
... return (fn(x) if i in pos_lst else x for (i,x) in enumerate(iterable))
...
>>> ''.join(apply_at(str.upper, [2,4,6,8], "abcdefghijklmno"))
'abCdEfGhIjklmno'
Run Code Online (Sandbox Code Playgroud)
我评论支持你的第一个片段,但这里还有其他几种记录方式:
(lambda (a,b,c): [a,b.upper(),c])(inp)
Run Code Online (Sandbox Code Playgroud)
(在 Python 3.x 中不起作用。)并且:
[inp[0], inp[1].upper(), inp[2]]
Run Code Online (Sandbox Code Playgroud)