2017-08-20 21 views
1

我有这个名单中的Python:如何更换每2特定单词列表中的

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

我想更换每秒BananaPear(这应该是结果):

['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] 

回答

1

你可以使用一个列表COMPR ehension得到的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'] 
+0

有没有办法做到这一点没有“特殊”自动替换命令? –

+0

@JohnWinston是的,我添加了一个使用生成器函数的解决方案。不知道这是你的意思,但它的工作原理,并不能取代原来的。 :) – MSeifert

+0

thx的答案,顺便说一句'yield'和'cnt'做什么? –

0

(只是想指出,你预期的结果不会显示你Pear更换每秒Banana,就说明你更换了第一和第三Banana,而不是第二个。如果这真的是你想要的,你可以在我下面的代码更改shouldReplace = FalseshouldReplace = True。)

MSeifert的解决方案是光滑,非常翔实我作为一个开始Python的用户,而只是指向另一种方式来做到这一点在地方改变你的名单将是这样的:

def replaceEverySecondInstance(searchWord, replaceWord): 
    shouldReplace = False 
    for index, word in enumerate(words): 
     if word == searchWord: 
      if shouldReplace == True: 
       words[index] = replaceWord 
      shouldReplace = not shouldReplace 

运行

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

提供了以下的输出:

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

这里是一个通用的方法,通过自上次更换倒计时的话occurances作品:

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 

=>list(replace(fruits, 2, first=True))

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

=>list(replace(fruits, 2, first=False))

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

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'] 
相关问题