我正在使用python开发一个函数。这是我的内容:
list = ['cow','orange','mango']
to_replace = 'orange'
replace_with = ['banana','cream']
所以我希望我的名单在替换后变成这样的
list = ['cow','banana','cream','mango']
我正在使用此功能:
def replace_item(list, to_replace, replace_with):
for n,i in enumerate(list):
if i== to_replace:
list[n]=replace_with
return list
它输出如下列表:
['cow', ['banana', 'cream'], 'mango']
那么如何修改此函数以获得以下输出?
list = ['cow','banana','cream','mango']
注意:我在这里找到了答案:Replacing list item with contents of another list 但我不想让词典参与其中。我还想修改我当前的功能,并保持简单直接。
答案 0 :(得分:5)
这种方法相当简单,与@ TadhgMcDonald-Jensen的iter_replace()
方法具有相似的性能(对我来说是3.6μs):
lst = ['cow','orange','mango']
to_replace = 'orange'
replace_with = ['banana','cream']
def replace_item(lst, to_replace, replace_with):
return sum((replace_with if i==to_replace else [i] for i in lst), [])
print replace_item(lst, to_replace, replace_with)
# ['cow', 'banana', 'cream', 'mango']
这是使用itertools类似的东西,但速度较慢(5.3μs):
import itertools
def replace_item(lst, to_replace, replace_with):
return list(itertools.chain.from_iterable(
replace_with if i==to_replace else [i] for i in lst
))
或者,这是使用两级列表理解(1.8μs)的更快方法:
def replace_item(lst, to_replace, replace_with):
return [j for i in lst for j in (replace_with if i==to_replace else [i])]
或者这是一个简单易读的版本(1.2μs):
def replace_item(lst, to_replace, replace_with):
result = []
for i in lst:
if i == to_replace:
result.extend(replace_with)
else:
result.append(i)
return result
与此处的某些答案不同,如果有多个匹配项,这些答案会进行多次替换。它们也比反转列表或重复将值插入现有列表更有效(python每次执行时都会重写列表的其余部分,但这只会重写列表一次)。
答案 1 :(得分:5)
在迭代过程中修改列表通常会产生问题,因为索引会发生变化。我建议放弃使用for循环的方法。
这是少数while
循环比for
循环更清晰,更简单的情况之一:
>>> list_ = ['cow','orange','mango']
>>> to_replace = 'orange'
>>> replace_with = ['banana','cream']
>>> while True:
... try:
... i = list_.index(to_replace)
... except ValueError:
... break
... else:
... list_[i:i+1] = replace_with
...
>>> list_
['cow', 'banana', 'cream', 'mango']
答案 2 :(得分:3)
首先,永远不要使用python内置名称和关键字作为变量名称(将list
更改为ls
)。
您不需要循环,找到索引然后链接切片:
In [107]: from itertools import chain
In [108]: ls = ['cow','orange','mango']
In [109]: to_replace = 'orange'
In [110]: replace_with = ['banana','cream']
In [112]: idx = ls.index(to_replace)
In [116]: list(chain(ls[:idx], replace_with, ls[idx+1:]))
Out[116]: ['cow', 'banana', 'cream', 'mango']
在python 3.5+中,您可以使用就地解包:
[*ls[:idx], *replace_with, *ls[idx+1:]]
答案 3 :(得分:3)
表示这样的规则的一种简单方法是使用生成器,当to_replace
看到不同的项目产生时:
def iter_replace(iterable, to_replace, replace_with):
for item in iterable:
if item == to_replace:
yield from replace_with
else:
yield item
然后,您可以list(iter_replace(...))
获得所需的结果,只要您不隐藏名称list
即可。
ls = ['cow','orange','mango']
to_replace = 'orange'
replace_with = ['banana','cream']
print(list(iter_replace(ls,to_replace,replace_with)))
# ['cow', 'banana', 'cream', 'mango']
答案 4 :(得分:-1)
def replace_item(list, to_replace, replace_with):
index = list.index(to_replace) # the index where should be replaced
list.pop(index) # pop it out
for value_to_add in reversed(replace_with):
list.insert(index, value_to_add) # insert the new value at the right place
return list