将函数应用于Python中列表的一个元素

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)

有没有更好的办法?谢谢!

Dav*_*rby 6

这是一个适用于任何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)


Dar*_*con 2

我评论支持你的第一个片段,但这里还有其他几种记录方式:

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