如何替换列表中的每个第二个特定单词

时间:2017-08-20 15:47:22

标签: python python-2.7 list replace

我在python中有这个列表:

['Banana', 'Apple', 'John', 'Banana', 'Food', 'Banana']

我想用Banana替换每一秒Pear(这应该是结果):

['Pear', 'Apple', 'John', 'Banana', 'Food', 'Pear']

我已经有了这段代码:

with open('text,txt') as f:
    words = f.read().split()

words_B = [word if word != 'Banana' else 'Pear' for word in words]

4 个答案:

答案 0 :(得分:1)

您可以使用列表推导来获取Banana的所有索引,然后切片以获取这些索引的每一秒,然后将相应的列表项设置为Pear

>>> l = ['Banana', 'Apple', 'John', 'Banana', 'Food', 'Banana']
>>> for idx in [idx for idx, name in enumerate(l) if name == 'Banana'][::2]:
...     l[idx] = 'Pear'
>>> l
['Pear', 'Apple', 'John', 'Banana', 'Food', 'Pear']

除了理解和切片之外,您还可以使用生成器表达式和itertools.islice

>>> from itertools import islice
>>> l = ['Banana', 'Apple', 'John', 'Banana', 'Food', 'Banana']
>>> for idx in islice((idx for idx, name in enumerate(l) if name == 'Banana'), None, None, 2):
...     l[idx] = 'Pear'
>>> l
['Pear', 'Apple', 'John', 'Banana', 'Food', 'Pear']

另一种可能性,特别是如果您不想就地更改列表,将创建自己的生成器函数:

def replace_every_second(inp, needle, repl):
    cnt = 0
    for item in inp:
        if item == needle:    # is it a match?
            if cnt % 2 == 0:  # is it a second occurence?
                yield repl
            else: 
                yield item
            cnt += 1          # always increase the counter
        else:
            yield item

>>> l = ['Banana', 'Apple', 'John', 'Banana', 'Food', 'Banana']
>>> list(replace_every_second(l, 'Banana', 'Pear'))
['Pear', 'Apple', 'John', 'Banana', 'Food', 'Pear']

答案 1 :(得分:0)

(只是要指出,您的预期结果并未显示您每隔Banana替换Pear,它会显示您替换第一个和第三个Banana,而不是第二个shouldReplace = False如果确实如此,您可以在我的以下代码中将shouldReplace = True更改为def replaceEverySecondInstance(searchWord, replaceWord): shouldReplace = False for index, word in enumerate(words): if word == searchWord: if shouldReplace == True: words[index] = replaceWord shouldReplace = not shouldReplace 。)

MSeifert的解决方案很灵活,对我来说非常有用,作为一个初学的Python用户,但只是指出另一种方法来改变你的列表就是这样的:

print(words)
replaceEverySecondInstance('Banana', 'Pear')
print(words)

运行

['Banana', 'Apple', 'John', 'Banana', 'Food', 'Banana']
['Banana', 'Apple', 'John', 'Pear', 'Food', 'Banana']

提供以下输出:

@Provider
@Priority(value = 1)
public class SecurityCheckRequestFilter implements ContainerRequestFilter
{
    @Override
    public void filter(ContainerRequestContext requestContext) throws IOException
    {
        //CODE

        requestContext.getUriInfo().getPathParameters().putSingle("userId", someNewUserId);
    }
}

答案 2 :(得分:0)

这是一种通用的方法,通过倒数自上次替换以来的单词出现来起作用:

from collections import defaultdict

d = defaultdict(int)
r = {
    'Banana': 'Pear',
}

fruits = ['Banana', 'Apple', 'John', 'Banana', 'Food', 'Banana']

def replace(fruits, every, first=True):
  for f in fruits:
    # see if current fruit f should be replaced
    if f in r:
        # count down occurence since last change
        # -- start at 1 if first should be changed otherwise 0
        d.setdefault(f, int(not first))
        d[f] -= 1
        # if we have reached count down, replace
        if d[f] < 0:
            yield r[f]
            d[f] = every - 1 
            continue
    # otherwise append fruit as is
    yield f

=&GT; list(replace(fruits, 2, first=True))

['Pear', 'Apple', 'John', 'Banana', 'Food', 'Pear']

=&GT; list(replace(fruits, 2, first=False))

['Banana', 'Apple', 'John', 'Pear', 'Food', 'Banana']

答案 3 :(得分:0)

有点令人费解,但我想我会把它扔出去。您可以使用itertools.cycle辅助函数在香蕉和梨之间交替,其中元素是香蕉或只是原始值,例如:

from itertools import cycle

data = ['Banana', 'Apple', 'John', 'Banana', 'Food', 'Banana']
b2p = lambda L,c=cycle(['Banana', 'Pear']): next(c) if L == 'Banana' else L
replaced = [b2p(el) for el in data]
# ['Banana', 'Apple', 'John', 'Pear', 'Food', 'Banana']