如何只替换子字符串而不是整个字符串?

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]

【讨论】:

以上是关于如何只替换子字符串而不是整个字符串?的主要内容,如果未能解决你的问题,请参考以下文章

如何从给定的整个 NSString 计算相同的子字符串

如何替换 Javascript 中的正则表达式子字符串匹配?

如何在JAVA中用不同的子字符串替换字符串的子字符串?

Postgresql 中的 REGEXP_REPLACE 不是子字符串

如何在 Netezza 中替换完整的子字符串

如何替换字符串的多个子串?