Python使用元组替换列表值

3

如果我有一个列表:

my_list = [3,2,2,3,4,1,3,4]

以及一个元组

my_tuple = (3,5)

使用元组替换my_list中的元素,最佳方法是什么:

result = [5,2,2,5,4,1,5,4]

e.g.

for item in my_list:
    if(item == my_tuple[0]):
        item = my_tuple[1]

更一般地,我会有一个列表的列表和一个元组的列表,我想将每个元组应用到列表的列表中的每个列表。

你的示例中的方法基本上是正确的,但是赋值语句不起作用,因为你正在处理列表中值的副本。你需要枚举列表并在满足条件时替换正确索引处的值。(对于简单情况,列表推导式更好,但对于列表和元组的列表可能会变得很丑陋)。 - Wooble
我仍然感到困惑,不知道 Python 何时会进行复制并使用引用... - tdc
不要感到困惑,这非常简单:Python 始终使用引用 - kindall
除了上面的item是一个副本! - tdc
1
item实际上将是对my_list中元素的引用,但由于my_list仅包含不可变类型,这并不会有太大影响。如果my_list是一个列表的列表,你可以像这样做:item[:] = [1, 2]并修改my_list的内容。 - Andrew Clark
4个回答

11

my_tuple 的更自然的数据结构是字典。考虑使用以下内容并使用 .get() 方法:

>>> my_lists = [[3,2,2,3,4,1,3,4], [1,2,3,4,5,6]]
>>> my_tuple_list = [(3,5), (6, 7)]
>>> my_dict = dict(my_tuple_list)
>>> my_dict
{3: 5, 6: 7}
>>> my_lists = [[my_dict.get(x,x) for x in somelist] for somelist in my_lists]
>>> my_lists
[[5, 2, 2, 5, 4, 1, 5, 4], [1, 2, 5, 4, 5, 7]]

get(x, x) ... 真美! - juliomalegria
太棒了!我没有想到可以使用字典,这很有道理。 - tdc

3
根据@Wooble的评论,如果你枚举一下代码,它就能正常工作。
list_of_lists = [[3,2,2,3,4,1,3,4], [1,3,5,3,4,6,3]]
list_of_tuples = [(3,5), (1,9)]

def tup_replace(mylist, mytuple):
    for i, item in enumerate(mylist):
        if item == mytuple[0]:
            mylist[i] = mytuple[1]
    return mylist

那么,您只需要将其嵌套更多以处理列表和元组的列表。
for mylist in list_of_lists:
    for mytuple in list_of_tuples:
        mylist = tup_replace(mylist, mytuple)
    print mylist

那么,字典方法可能更好。

1
+1,因为我认为有不同方法的多个答案(即使有些效率较低)比一堆相似的答案更有意义,这些答案会逐渐演变成彼此。在我看来,每个问题通常应该至少有两个答案:一个是解释如何修复 OP 代码中明显的问题,另一个是解释 OP 应该如何在第一时间解决问题。 - DSM

1
如果你想要将列表中的每个 3 替换为 5,可以使用以下代码:
[x == my_tuple[0] and my_tuple[1] or x for x in my_list]

如果您想要使用多个“翻译”元组来完成此操作,我强烈建议使用字典代替:
trans = {3: 5, 4: 6}
[trans.get(x,x) for x in my_list]

而在你有多个列表的更一般情况下:

ll = [[3, 2, 3, 4], [5, 4, 3, 4]]
trans = {3: 5, 4: 6}
for i in range(len(ll)):
    ll[i] = [trans.get(x,x) for x in ll[i]]

假设您想要用新列表替换ll中的每个旧列表。


@PlatinumAzure:OP 问如何在多个列表和翻译元组中实现此操作,我刚刚更新了我的答案。 - Rik Poggi

1

在一般情况下,如果使用 if item == my_tuple[0],... 这种方式,会让人感觉你想要为列表中的每个项目都创建一个 switch 语句。如果可能的话,最好使用字典。(为什么 Python 中没有 switch 或 case 语句?)

将元组列表转换为查找字典(Python 的 switch 语句):

replacements = dict(my_tuples) #thanks to @julio

对于单个列表,使用推导式重新生成该列表,但如果存在替换的新值,则将每个值替换为该新值:

replaced_list = [replacements.get(original,original) for original in my_list]

我猜应该有更高效的方法去做这件事,但这只适用于一个列表里带有元组的情况。你说你需要对一个列表里的多个列表进行操作?那不就嵌套一下吗?

可以再详细解释下你获取数据的来源以及为什么要这样做吗?


更Pythonic的写法:replacements = dict(my_tuples) - juliomalegria
我不知道这一点。谢谢,我会更新答案。更重要的是,我错过了替换中没有所有项目的情况。 - KobeJohn

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接