【问题标题】:Replacing only first occurrence of characters in list items in python?只替换python列表项中第一次出现的字符?
【发布时间】:2012-09-03 21:50:22
【问题描述】:

这很难解释,但这是我的问题..

sampleList = ['_ This is an item.','__ This is also an item']

我正在尝试获取 sampleList 并查找 _ 是否仅出现在第一个字符行中,将其替换为 #,然后如果出现 __,则替换为 &

即使是我自己也有点难以理解。

基本上,如果我有一个列表,我希望它通过列表工作,只找到可能的 dict 的第一个实例并将其替换为相应的值。然后返回整个列表..

编辑:

如果描述性不够,请见谅..

dictarray = {
'_':'&',
'__':'*#',
'____':'*$(@'
}

sampleList = ['_ This is an item.','__ This is also an item','_ just another _ item','____ and this last one']

输出:

sampleList = ['& This is an item.','*# This is also an item','& just another _ item','*$(@ and this last one']

如果在项目的开头找到键,我需要能够捕获,如果是,请将其更改为值。

【问题讨论】:

  • 我们还需要查看其他结构。
  • 你能举几个sampleList的各种值的预期返回值的例子吗?
  • 你们去了,有帮助吗?
  • 你总是想替换第一个,还是只替换第一个 if 行以它开头?例如。 “不太_”应该保持“不太_”还是变成“不太&”?
  • 它应该保持为'Not quite _'

标签: python string list replace


【解决方案1】:
# The original input data
dictarray = {
'_':'&',
'__':'*#',
'____':'*$(@'
}

sampleList = ['_ This is an item.','__ This is also an item','_ just another _ item','____ and this last one']

# Order the substitutions so the longest are first.
subs = sorted(dictarray.items(), key=lambda pair: len(pair[0]), reverse=True)

def replace_first(s, subs):
    """Replace the prefix of `s` that first appears in `subs`."""
    for old, new in subs:
        if s.startswith(old):
            # replace takes a count of the number of replacements to do.
            return s.replace(old, new, 1)
    return s

# make a new list by replace_first'ing all the strings.
new_list = [replace_first(s, subs) for s in sampleList]

print new_list

产生:

['& This is an item.', '*# This is also an item', '& just another _ item', '*$(@ and this last one']

在这里,我已经对 dictarray 进行了修改,以首先对最长的替换进行排序,因此较短的前缀不会排除较长的前缀。

【讨论】:

  • “一个明显的方法”,我猜:我的线路是d_sorted = sorted(d.items(), key=lambda kv: len(kv[0]), reverse=True)。 :^)
  • @DSM:如果有一种明显的方式来命名所有变量就好了! :)
  • 完美!哇,这个地方真是难以置信。不过,现在我只想添加一件事。我将在列表中列出需要替换所有键的项目的实例。因此,如果%%% 在一个项目中出现十二次,则需要全部替换十二次。但是这条规则只适用于特定的键。这甚至可能吗?
  • 花了我一秒钟才看到它,但这是一个非常优雅的解决方案。 +1,确实是“一种明显的方法”。
【解决方案2】:

这里的诀窍是将较长的下划线(__)放在if 条件中,然后将较小的下划线(_)放在elif 条件中:

dic = {
'_':'&',
'__':'*#',
'____':'*$(@'
}
lis=['_ This is an item.','__ This is also an item','_ just another _ item','____ and this last one']
for x in sorted(dic,key=len,reverse=True):
    for i,y in enumerate(lis):
        if y.startswith(x):
            lis[i]=y.replace(x,dic[x])

print(lis)

输出:

['& This is an item.', '*# This is also an item', '& just another & item', '*$(@ and this last one']

【讨论】:

  • 硬编码一切似乎不是很健壮。
  • @DSM OP 没有在原始问题中提到字典,所以这就是为什么我使用硬编码的ifelif
  • 实际上,OP 确实——“只找到 possible dict 的第一个实例”——但即使他没有,硬编码每一行仍然是一个坏主意,因为它使代码依赖于值。
猜你喜欢
  • 2011-06-05
  • 1970-01-01
  • 2022-10-07
  • 1970-01-01
  • 1970-01-01
  • 2018-10-30
  • 1970-01-01
  • 2011-08-25
  • 2016-11-02
相关资源
最近更新 更多