Python:列表中的查找替换

时间:2015-12-09 09:06:17

标签: python

我首先要注意的是,我的问题与此链接中的内容不同: finding and replacing elements in a list (python)

我想问的是,是否有一些已知的API或传统方式来实现这样的功能(如果不清楚,像我想象的list_replace()这样的函数/方法是我正在寻找的):

>>> list = [1, 2, 3]
>>> list_replace(list, 3, [3, 4, 5])
>>> list
[1, 2, 3, 4, 5]

限制更换次数的API会更好:

>>> list = [1, 2, 3, 3, 3]
>>> list_replace(list, 3, [8, 8], 2)
>>> list
[1, 2, 8, 8, 8, 8, 3]

另一个可选的改进是,要替换的输入将是一个列表本身,而不是单个值:

>>> list = [1, 2, 3, 3, 3]
>>> list_replace(list, [2, 3], [8, 8], 2)
>>> list
[1, 8, 8, 3, 3]

是否有任何API看起来至少相似并执行这些操作,或者我应该自己编写?

5 个答案:

答案 0 :(得分:1)

尝试;

def list_replace(ls, val, l_insert, num = 1):
    l_insert_len = len(l_insert)
    indx = 0
    for i in range(num):
        indx = ls.index(val, indx) #it throw value error if it cannot find an index
        ls = ls[:indx] + l_insert + ls[(indx + 1):]
        indx += l_insert_len
    return ls

此功能适用于第一种和第二种情况;
它不符合你的第三个要求

演示

>>> list = [1, 2, 3]
>>> list_replace(list, 3, [3, 4, 5])
[1, 2, 3, 4, 5]
>>> list = [1, 2, 3, 3, 3]
>>> list_replace(list, 3, [8, 8], 2)
[1, 2, 8, 8, 8, 8, 3]

注意 它返回一个新列表;传入的列表不会改变。

答案 1 :(得分:1)

这个怎么样,它适用于3个要求

def list_replace(origen,elem,new,cantidad=None):
    n=0
    resul=list()
    len_elem=0
    if isinstance(elem,list):
        len_elem=len(elem)
    for i,x in enumerate(origen):
        if x==elem or elem==origen[i:i+len_elem]:
            if cantidad and n<cantidad:
                resul.extend(new)
                n+=1
                continue
            elif not cantidad:
                resul.extend(new)
                continue
        resul.append(x)
    return resul



>>>list_replace([1,2,3,4,5,3,5,33,23,3],3,[42,42])
[1, 2, 42, 42, 4, 5, 42, 42, 5, 33, 23, 42, 42]
>>>list_replace([1,2,3,4,5,3,5,33,23,3],3,[42,42],2)
[1, 2, 42, 42, 4, 5, 42, 42, 5, 33, 23, 3]
>>>list_replace([1,2,3,4,5,3,5,33,23,3],[33,23],[42,42,42],2)
[1, 2, 3, 4, 5, 3, 5, 42, 42, 42, 23, 3]

答案 2 :(得分:0)

鉴于这并不难写,而且不是一个非常常见的用例,我认为它不会出现在标准库中。它的名字是什么,replace_and_flatten?很难解释它的作用,并证明其包容性。

明确也比隐含更好,所以......

def replace_and_flatten(lst, searched_item, new_list):
    def _replace():
        for item in lst:
            if item == searched_item:
                yield from new_list  # element matches, yield all the elements of the new list instead
            else:
                yield item  # element doesn't match, yield it as is

    return list(_replace())  # convert the iterable back to a list

答案 3 :(得分:0)

我开发了自己的功能,欢迎您使用并查看它。

请注意,与问题中的示例相矛盾 - 我的函数创建并返回一个新列表。它修改提供的列表。

工作示例:

list = [1, 2, 3]
l2 = list_replace(list, [3], [3, 4, 5])
print('Changed: {0}'.format(l2))
print('Original: {0}'.format(list))

list = [1, 2, 3, 3, 3]
l2 = list_replace(list, [3], [8, 8], 2)
print('Changed: {0}'.format(l2))
print('Original: {0}'.format(list))

list = [1, 2, 3, 3, 3]
l2 = list_replace(list, [2, 3], [8, 8], 2)
print('Changed: {0}'.format(l2))
print('Original: {0}'.format(list))

我总是打印原始列表,因此您可以看到它未被修改:

Changed: [1, 2, 3, 4, 5]
Original: [1, 2, 3]
Changed: [1, 2, 8, 8, 8, 8, 3]
Original: [1, 2, 3, 3, 3]
Changed: [1, 8, 8, 3, 3]
Original: [1, 2, 3, 3, 3]

现在,代码(使用Python 2.7和Python 3.4测试):

def list_replace(lst, source_sequence, target_sequence, limit=0):
    if limit < 0:
        raise Exception('A negative replacement limit is not supported')
    source_sequence_len = len(source_sequence)
    target_sequence_len = len(target_sequence)
    original_list_len = len(lst)
    if source_sequence_len > original_list_len:
        return list(lst)
    new_list = []
    i = 0
    replace_counter = 0
    while i < original_list_len:
        suffix_is_long_enough = source_sequence_len <= (original_list_len - i)
        limit_is_satisfied = (limit == 0 or replace_counter < limit)
        if suffix_is_long_enough and limit_is_satisfied:
            if lst[i:i + source_sequence_len] == source_sequence:
                new_list.extend(target_sequence)
                i += source_sequence_len
                replace_counter += 1
                continue
        new_list.append(lst[i])
        i += 1      
    return new_list

答案 4 :(得分:0)

我为你开发了一个功能(它适用于你的3个要求):

print list_replace([1,2,3], 3, [3, 4, 5])
print list_replace([1, 2, 3, 3, 3], 3, [8, 8], 2)
print list_replace([1, 2, 3, 3, 3], [2, 3], [8, 8], 2)

我已尝试过您的示例,但效果还不错。

测试:

list

注意:切勿使用is list作为变量。我需要该对象来执行{{1}}技巧。