Python 修改列表删除元素而不造成混乱

Python 修改列表删除元素而不造成混乱,python,list,python-3.x,Python,List,Python 3.x,我现在正试图解决一个听起来像这样的任务: ''编写一个函数modi(la,lb),该函数接受输入2,列出内部元素数相同的la和lb。函数应修改在两个列表中列出具有相同索引的la和lb camparing元素,并删除一个较大的元素,如果元素相等,函数将同时删除这两个元素。“” 例如: la=[“熊”、“老虎”、“狼”、“鲸鱼”、“大象”] lb=[“天鹅”、“猫”、“狗”、“鸭”、“兔子”] 因此functin应该返回: [‘熊’、‘大象’] [‘猫’、‘狗’、‘鸭’] 我已经编写了下一段代码

我现在正试图解决一个听起来像这样的任务:

''编写一个函数modi(la,lb),该函数接受输入2,列出内部元素数相同的la和lb。函数应修改在两个列表中列出具有相同索引的la和lb camparing元素,并删除一个较大的元素,如果元素相等,函数将同时删除这两个元素。“”

例如:

  • la=[“熊”、“老虎”、“狼”、“鲸鱼”、“大象”]
  • lb=[“天鹅”、“猫”、“狗”、“鸭”、“兔子”]
因此functin应该返回: [‘熊’、‘大象’] [‘猫’、‘狗’、‘鸭’]

我已经编写了下一段代码,但它不会修改列表,而是创建新的列表并在其中添加元素。我该怎么做

def confront(s1, s2):   

    if s1 < s2:   # condition that tells which element to choose later
        return 0
    elif s2 < s1:
        return 1
    else:
        return 2


def modi(la,lb):

    latemp = []

    lbtemp = []

    i = 0

    while i < len(la):


        q = confront(la[i], lb[i])
        if q == 0:
            latemp.append(la[i])

        elif q == 1:
            lbtemp.append(lb[i])


        i +=1  
    la = latemp
    lb = lbtemp
    return la, lb
def(s1,s2):
如果s1

我尝试过remove(),但它造成了一片混乱

您应该使用
del
删除列表项。此外,您还应该从头到脚进行迭代,因为如果您要从头开始删除,比如说
1st
元素,则位于
3rd
位置的元素现在将位于
2nd

应该是这样的

#you need to handle what if len of lists is 0, if lens are not the same and so on...
def compare_and_delete(list1, list2):
    i = len(list1) -1
    while i >= 0:
        if list1[i] > list2[i]:
            del list1[i]
        elif list2[i] > list1[i]:
            del list2[i]
        else:
            del list1[i]
            del list2[i]

        i-=1

        return list1, list2

l1, l2 = compare_and_delete(['bear', 'tiger', 'wolf', 'whale', 'elephant'], ['swan', 'cat', 'dog', 'duck', 'rabbit'])

您可以利用分配给切片会修改列表这一事实:

la[:] = latemp
lb[:] = lbtemp

通常,当您在迭代列表时对其进行变异时。最好的做法是迭代一个副本。下面是一个示例,说明如何更改一个列表

list = []
list_copy = list[:]
for i in list_copy:
    list.remove(i)
return list
这允许您在每次迭代中维护正确的索引

下面是我试图解释我的意思,并使用for循环来获得预期的结果。希望能有帮助

def confront(s1, s2):

if s1 < s2:   # condition that tells which element to choose later
    return 0
elif s2 < s1:
    return 1
else:
    return 2


def modi(la,lb):
    la_copy = la[:]
    lb_copy = lb[:]

    for i in range(len(la_copy)):
        q = confront(la_copy[i], lb_copy[i])
        if q == 0:
            lb.remove(lb_copy[i])
        elif q == 1:
            la.remove(la_copy[i])

    return la, lb


la = ['bear', 'tiger', 'wolf', 'whale', 'elephant']
lb = ['swan', 'cat', 'dog', 'duck', 'rabbit']

这会解决你的问题。我认为这比所有其他解决方案都简单

def modi(la, lb):
    new_la = []
    new_lb = []
    for a, b in zip(la, lb):
        if a == b:
            continue
        if a > b:
            new_lb.append(b)
        if a < b:
            new_la.append(a)
    return new_la, new_lb
def modi(la,lb):
new_la=[]
新的_lb=[]
对于拉链中的a、b(la、lb):
如果a==b:
持续
如果a>b:
新增(b)
如果a
但是,如果要更改现有列表,可以执行以下操作:

def modi(la, lb):
    del_la = []
    del_lb = []
    for i, (a, b) in enumerate(zip(la, lb)):
        if a == b:
            del_la.append(i)
            del_lb.append(i)
        if a > b:
            del_la.append(i)
        if a < b:
            del_lb.append(i)
    for x in del_la[-1::-1]:
        del la[x]
    for x in del_lb[-1::-1]:
        del lb[x]
    return la, lb
def modi(la,lb):
德拉=[]
del_lb=[]
对于枚举中的i(a,b)(zip(la,lb)):
如果a==b:
del_la.追加(i)
del_lb.追加(i)
如果a>b:
del_la.追加(i)
如果a
在您自己的代码中
la=latemp
lb=lbtemp
创建对函数本地的两个新列表的引用,它们与传递给函数的列表无关。根据您的规范,您应该修改传入的列表,而不是重新分配或创建新列表

由于您正在进行元素级比较,因此可以根据您的规格使用zip并从每个列表中删除:

def modi(la, lb):
    for i, j in zip(la, lb):
        # both the same
        if i == j:
            la.remove(i) 
            lb.remove(i)
        # element from la is bigger
        elif i > j:
            la.remove(i)
        # else element from lb must be bigger
        else:
            lb.remove(j)


la = ['bear', 'tiger', 'wolf', 'whale', 'elephant']
lb = ['swan', 'cat', 'dog', 'duck', 'rabbit']

modi(la, lb) # will modify the lists passed in.

print(la, lb) 

本质上,您需要跟踪您从每个列表中删除了多少次,并将索引偏移该数量。以下是一个基本方法:

>>> a
['bear', 'tiger', 'wolf', 'whale', 'elephant']
>>> b
['swan', 'cat', 'dog', 'duck', 'rabbit']
>>> i = j = 0
>>> for k, (str1,str2) in enumerate(zip(a,b)):
...     if len(str1) == len(str2):
...         del a[k-i], b[k-j]
...         i += 1
...         j += 1
...     elif len(str1) > len(str2):
...         del a[k-i]
...         i += 1
...     else:
...         del b[k-j]
...         j += 1
... 
>>> a
[]
>>> b
['cat', 'dog', 'duck', 'rabbit']
>>> 

modi(la,lb)
函数应该修改列表
la
lb
,但您的解决方案没有。这就是问题所在。我的做法与在开始时创建空列表并在其中添加元素的方法完全相同,因此最后我返回新列表。我添加了另一个解决方案(基于第一个解决方案)以更改现有列表。抱歉,我没有看到您的第二个代码!现在我明白了,我想问“enumerate(zip(la,lb))”是什么意思
zip
用于同时浏览两个列表,直到到达较短列表的末尾
enumerate
只为
循环枚举
中的过程(这很适合以后用作索引)。如果你喜欢这个答案,请接受。谢谢!我有一个问题,一个只学了三周编程的无知者:返回这个函数的是什么?因为当我运行它时,它不会返回任何东西……是的-你需要添加返回语句检查我的编辑器答案不应该是
[]
['cat','dog','duck','rabbit']
>>> a
['bear', 'tiger', 'wolf', 'whale', 'elephant']
>>> b
['swan', 'cat', 'dog', 'duck', 'rabbit']
>>> i = j = 0
>>> for k, (str1,str2) in enumerate(zip(a,b)):
...     if len(str1) == len(str2):
...         del a[k-i], b[k-j]
...         i += 1
...         j += 1
...     elif len(str1) > len(str2):
...         del a[k-i]
...         i += 1
...     else:
...         del b[k-j]
...         j += 1
... 
>>> a
[]
>>> b
['cat', 'dog', 'duck', 'rabbit']
>>>