我可以有条件地突变列表吗?



这可能已经回答,但我在搜索中找不到。

在Python 3中,我发现自己写了很多看起来像这样的代码:

def func():
    for item in list_A:
        if item == 'duck': list_B.append(0)
        elif item == 'goose': list_B.append(1)
        else: list_B.append(item)
    list_A = list_B

我的目的是有条件地更改list_a中的值。例如:

list_A = ['duck', 'duck', 'goose', 'duck', 'chicken']
func(list_A) -> [0, 0, 1, 0, 'chicken']

理想情况下,我想在不创建第二个列表的情况下执行此操作。我想找到以下psuedo代码之类的东西:

list_A = [(if item == 'duck': 0, elif item == 'goose': 1, else: item) for item in list_A]

我的直觉是,以上是不起作用的,因为您在迭代时无法突变列表(?(,但是如果有人比我的原始方法更好,我真的很感兴趣。谢谢!

迭代时替换列表中的元素是可以的。问题是结构性修改 - 添加元素,将其删除或导致元素转移的操作。

也就是说,创建第二个列表通常更容易正确,而且通常更快。

如果您想采用突变方法,这是您可以做到的一种方法:

for i, item in enumerate(l):
     if item == 'duck':
         l[i] = 0
     elif item == 'goose':
         l[i] = 1
def func(list_a):
  dict_a = {"duck":0,"goose":1}
  return [dict_a.get(item,item) for item in list_a]

您可以创建一个dict,然后将其用于映射。在这种情况下,可以在迭代时迭代列表,因为a(不更改尚未阅读的项目,b(不更改列表的长度。为了保持代码更紧凑,您可以使用dict.get()涵盖其他情况:

mapping = {'duck': 0, 'goose': 1}
for i, val in enumerate(list_A):
    list_A[i] = mapping.get(val, val)

或更快一些,但更多代码:

mapping = {'duck': 0, 'goose': 1}
for i, val in enumerate(list_A):
    if val in mapping:
        list_A[i] = mapping[val]

如果您可以创建一个新列表,则可以做

mapping = {'duck': 0, 'goose': 1}
list_B = [mapping.get(val, val) for val in list_A]
def func():
    list_A=['duck','dd']
    list_B=[]   
    dic = {'duck':0,'goose':1}
    for item in list_A:
        list_B.append(dic[item]) if item in dic  else list_B.append(item)
    print(list_B)
print(func())

输出

[0, 'dd']

最新更新