Python映射、Lambda和string.replace

Python映射、Lambda和string.replace,python,string,lambda,Python,String,Lambda,我知道如何在不使用lambda/map的情况下解决我的问题(在本练习中,我不能使用regex或其他python库),使用带有string.replace()的for循环……但我确实在尝试使用map/lambda和string.replace的组合是否能达到同样的效果\ 我的目标是读入一个txt文件,然后用字母“e”替换每个非标准的“e”(如“e”) 我现在的主要问题是我得到了6个列表(例如,我在newFile/newFileListComprehension中有6个字符串,并且每个字符串都根据评

我知道如何在不使用lambda/map的情况下解决我的问题(在本练习中,我不能使用regex或其他python库),使用带有string.replace()的for循环……但我确实在尝试使用map/lambda和string.replace的组合是否能达到同样的效果\

我的目标是读入一个txt文件,然后用字母“e”替换每个非标准的“e”(如“e”)

我现在的主要问题是我得到了6个列表(例如,我在newFile/newFileListComprehension中有6个字符串,并且每个字符串都根据评估的1个iterable更新了原始字符串)

e、 g.newFile[0]=输出.replace('e'),newFile[1]=输出.replace('e')等

所以我想返回格式化字符串的1个副本,所有的.replace()都在上面迭代

可以访问我下面引用的文本文件的链接


您可以使用
str.translate
一次替换多个字符。
str.maketrans
帮助您创建所需的映射:

eSToAvoid = 'éêèÉÊÈ'
textFile.translate(str.maketrans(eSToAvoid, 'e' * len(eSToAvoid)))

虽然
str.replace
只能用另一个子字符串替换一个子字符串,
re.sub
可以替换一个模式

In [55]: eSToAvoid = 'éêèÉÊÈ' 
In [58]: import re 
测试用例:

In [61]: re.sub(r'[éêèÉÊÈ]', 'e', 'foobar')                                                                          
Out[61]: 'foobar'
In [62]: re.sub(r'[éêèÉÊÈ]', 'e', eSToAvoid)                                                                         
Out[62]: 'eeeeee'
In [63]: re.sub(r'[éêèÉÊÈ]', 'e', 'testingè,É  foobar  è É')                                                         
Out[63]: 'testinge,e  foobar  e e'
字符串替换方法是:

In [70]: astr = 'testingè,É  foobar  è É' 
    ...: for e in eSToAvoid: 
    ...:     astr = astr.replace(e,'e') 
    ...:                                                                                                             
In [71]: astr                                                                                                        
Out[71]: 'testinge,e  foobar  e e'
替换按顺序应用于
astr
。这不能表示为列表理解(或
map
)。列表理解最自然地替换在列表中收集其结果的循环(使用
list.append

for循环没有问题。它实际上更快:

In [72]: %%timeit 
    ...: astr = 'testingè,É  foobar  è É' 
    ...: for e in eSToAvoid: 
    ...:     astr = astr.replace(e,'e') 
    ...:  
    ...:                                                                                                             
1.37 µs ± 8.96 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

In [73]: timeit re.sub(r'[éêèÉÊÈ]', 'e', 'testingè,É  foobar  è É')                                                  
2.79 µs ± 15.3 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

In [77]: timeit astr.translate(str.maketrans(eSToAvoid, 'e' * len(eSToAvoid)))                                       
2.56 µs ± 14.5 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
减少 为了好玩,您还可以探索此处介绍的一些想法:

您想要“累积”更改,要做到这一点,您需要某种类型的累加器,这种累加器挂在最后一次替换上。
itertools
具有
累积
功能,Py 3.8引入了
:=
海象操作符

发电机
[s代表foo中的s(astr,eSToAvoid)]
代替
列表()
。这突出了一个事实,即列表理解返回一个字符串列表,即使字符串累积了更改。

列表理解很容易根据您的代码行进行调整。这就是您想要的吗?老实说,JF,我尝试使用列表理解,但效果似乎更差……我假设列表理解是可行的更难的是,从本质上来说,它会为列表中的“每个”值创建一个iterable列表……但也许我错了?”我认为列表理解会更难,因为从本质上来说,它会为列表中的“每个”值创建一个iterable列表我不知道这意味着什么,但列表理解本质上是编写生成列表的
映射
/
筛选
操作的一种便捷方式。在任何情况下,您都可以提供一个例子,通常不会很好地接受这些模糊的描述。请注意,数据来自文本文件的事实并不真实y相关。只需给出输入和预期输出,以及您已经使用过的代码。注意,仅通过阅读您的描述,它听起来不像
map
是正确的解决方案。它听起来应该是
reduce
。但实际上,在Python中,您只需编写for循环。甚至
map
/
过滤器
通常在适当的地方避免。当然,juanpa,我用我的“尝试”更新了在这个问题的列表理解中…我尝试了它,但是得到了与map/reduceoh my差不多的结果…谢谢你分享这个方法。这个方法非常干净,我需要了解更多关于它的工作原理,但是它在我这方面运行得很好:)谢谢一位客人!很好的建议(我的条件之一是不使用正则表达式…)可以这么说,我使用列表理解或lambda/map组合的“尝试”根本无法“工作”以获得我想要的输出。列表理解生成一个列表。那不是你想要的,是吗?您需要一个链式应用程序,
astr.replace(…).replace(…).replace(…)
。可能会有一些诡计累积这些变化,但为什么呢?即使在简单的情况下,列表理解也只比等效循环稍微快一点。谢谢hpaulj.“为什么”只是反映了我对python了解的更多…所以我在此感谢您的见解
In [72]: %%timeit 
    ...: astr = 'testingè,É  foobar  è É' 
    ...: for e in eSToAvoid: 
    ...:     astr = astr.replace(e,'e') 
    ...:  
    ...:                                                                                                             
1.37 µs ± 8.96 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

In [73]: timeit re.sub(r'[éêèÉÊÈ]', 'e', 'testingè,É  foobar  è É')                                                  
2.79 µs ± 15.3 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

In [77]: timeit astr.translate(str.maketrans(eSToAvoid, 'e' * len(eSToAvoid)))                                       
2.56 µs ± 14.5 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
In [93]: from functools import reduce  
In [96]: reduce(lambda s,e: s.replace(e,'e'),eSToAvoid, 'testingè,É  foobar  è É' )                                  
Out[96]: 'testinge,e  foobar  e e'
In [97]: timeit reduce(lambda s,e: s.replace(e,'e'),eSToAvoid, 'testingè,É  foobar  è É' )                           
2.11 µs ± 32.1 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
In [110]: def foo(astr, es): 
     ...:     for e in es: 
     ...:         astr = astr.replace(e,'e') 
     ...:         yield astr 
     ...:                                                                                                            
In [111]: list(foo(astr, eSToAvoid))                                                                                 
Out[111]: 
['testingè,É  foobar  è É',
 'testingè,É  foobar  è É',
 'testinge,É  foobar  e É',
 'testinge,e  foobar  e e',
 'testinge,e  foobar  e e',
 'testinge,e  foobar  e e']