簡體   English   中英

Python:在列表中查找替換

[英]Python: Find-replace on lists

我首先要注意,我的問題與此鏈接的內容不同: 在列表中查找和替換元素(python)

我想問的是,是否有某種已知的API或常規方法來實現這種功能(如果不清楚,我list_replace()是像我想象中的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,還是我應該自己編寫?

嘗試;

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]

注意它將返回一個新列表; 傳入的列表不會更改。

怎么樣,它可以滿足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]

鑒於這並不難編寫,也不是很常見的用例,所以我認為它不會出現在標准庫中。 它將被命名為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

我開發了自己的功能,歡迎您使用和審查。

請注意,與問題中的示例相反,我的函數創建並返回了一個新列表。 修改提供的列表。

工作示例:

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

我為您開發了一個功能(它可以滿足您的3個要求):

def list_replace(lst,elem,repl,n=0):
    ii=0
    if type(repl) is not list:
        repl = [repl]
    if type(elem) is not list:
        elem = [elem]
    if type(elem) is list:
        length = len(elem)
    else:
        length = 1
    for i in range(len(lst)-(length-1)):
        if ii>=n and n!=0:
            break
        e = lst[i:i+length]
        if e==elem:
            lst[i:i+length] = repl
            if n!=0:
                ii+=1
    return lst

我已經嘗試了您的示例,但效果很好。

進行的測試:

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技巧。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM