使用其他列表中的项替换列表中的项而不使用词典

时间:2016-09-11 20:30:54

标签: python list

我正在使用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 但我不想让词典参与其中。我还想修改我当前的功能,并保持简单直接。

5 个答案:

答案 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