如何只替换子字符串而不是整个字符串?
Posted
技术标签:
【中文标题】如何只替换子字符串而不是整个字符串?【英文标题】:How to only replace substring not entire string? 【发布时间】:2019-02-13 02:04:24 【问题描述】:我有一本像这样的字典:
global_dict_names=dict'com':'owb_com','cur':'cur_con','cty':'gds_cty','cur':'gds_cur'
我的数据框如下所示:
com12 cur34 cty56 cur78
a b c d
b c d e
我希望我的数据框看起来像这样:
owb_com12 cur_con34 gds_cty56 gds_cur78
a b c d
b c d e
我当前的代码如下所示:
GDS2018_labels.columns = [global_dict_names.get(x[:3], x) for x in
GDS2018_labels.columns]
当前代码将列名的前三个字符与字典中的键匹配。这段代码的问题是它替换了整个列名,但我只想替换与键匹配的列名的子字符串。我该如何纠正这个问题?
【问题讨论】:
为什么你的字典有重复的'cur'
键?字典键是唯一的。
或许[x.replace(x[:3], global_dict_names.get(x[:3], x)) for x in GDS2018_labels.columns]
?
所以...GDS2018_labels.columns
是 - 并且应该保留 - 一个列表? global_dict_names
是什么?你能提供一些(半)工作代码吗?
【参考方案1】:
鉴于您的输入和所需的输出,dict
是错误的数据结构选择。字典键是唯一的,这是不可协商的。
您可以使用元组列表和列表推导:
L = [('com', 'owb_com'), ('cur', 'cur_con'), ('cty', 'gds_cty'), ('cur', 'gds_cur')]
df.columns = [name.replace(old, new) for name, (old, new) in zip(df.columns, L)]
print(df)
owb_com12 cur_con34 gds_cty56 gds_cur78
0 a b c d
1 b c d e
【讨论】:
再次感谢!为什么必须用字典压缩列? 得到了我的投票...我可能会想让它更明确一些,例如:[name.replace(old, new) for name, (old, new) in zip(df.columns, L)]
或类似的。
首先,我的解决方案没有字典。它有一个元组列表。其次,我确实使用zip
按顺序迭代列和元组。
谢谢!为什么你更喜欢使用元组列表而不是字典? (抱歉所有问题,我还在学习中)
字典不能有重复的键。您的示例将 'cur'
两次作为键。这是不允许的。【参考方案2】:
正如用户 jpp 所提到的,您不应该使用字典,因为您有两个相等的键。我在发布答案后才注意到这一点。检查他的答案,如果您将字典更改为只有相等的键,您只需使用+
即可简单地连接字符串。将前缀global_dict_names.get(x[:3], x[:3])
添加到后缀x[3:]
。
GDS2018_labels.columns = [global_dict_names.get(x[:3], x[:3]) + x[3:] for x in
GDS2018_labels.columns]
【讨论】:
以上是关于如何只替换子字符串而不是整个字符串?的主要内容,如果未能解决你的问题,请参考以下文章
如何替换 Javascript 中的正则表达式子字符串匹配?