获取新的唯一列表,仅包含原始列表中最后出现的元素

Get new unique list containg only last occuring elements from original list

对不起,我真的不知道如何命名我的问题。我正在寻找解决以下问题的 'most pythonic' 方法:

AA = [["a", 1], ["b", 1], ["c", 1], ["a", 3], ["b", 5], ["a", 7]]
BB = []
for elem in AA:
    if elem[0] not in [elemb[0] for elemb in BB]:
        BB.append(elem)
    else:
        BB[
            [belem[0] for belem in BB].index(elem[0])
        ] = elem
for elem in BB:
    print(elem)

也就是说:我有一个列表的列表,每个列表包含两个元素,现在我想把它变成一个新列表,原始列表的列表元素的每个第一个值只出现一次。

上面的代码解决了这个任务,即转

[["a", 1], ["b", 1], ["c", 1], ["a", 3], ["b", 5], ["a", 7]]

进入

[["a", 7], ["b", 5], ["c", 1]]

如我所愿,但不是很优雅,我怀疑这是否是最好的解决方案。

我通过使用字典想到了一个想法。简短版本为:

CC = {elem[0] : elem[1] for elem in AA}
BB = [[elem, CC[elem]] for elem in CC]
BB.sort()
for elem in BB:
    print(elem)

还有更长的(出于几个原因我需要它):

CC = {}
for elem in AA:
    try:
        oldelem = CC[elem[0]]
        CC[elem[0]] = elem[1]
        print("Element '{:}' replaced: {:d} -> {:d}".format(
            elem[0], oldelem, elem[1]
        ))
    except KeyError:
        CC[elem[0]] = elem[1]
BB = [[elem, CC[elem]] for elem in CC]
BB.sort()
for elem in BB:
    print(elem)

dict 的问题是,如果列表元素变得更复杂,它会变得有限制,并且对替换会有一些额外的限制(即某些值大于/小于元素的值)替换等)

所以现在我的问题是:是否有一个简短的/'better'/更简洁的方法来完成这个任务?

您可以使用 OrderedDict 来保留每对的最后一次出现:

>>> from collections import OrderedDict
>>> d=OrderedDict({i:j for i,j in AA})

>>> d.items()
[('a', 7), ('c', 1), ('b', 5)]

因为字典的新 key:value 赋值会自动覆盖旧的,所以答案很简单 dict():

>>> AA = [["a", 1], ["b", 1], ["c", 1], ["a", 3], ["b", 5], ["a", 7]]
>>> dict(AA)
{'a': 7, 'b': 5, 'c': 1}

比 Kasramvd 的答案略有改进:

>>> from collections import OrderedDict
>>> print OrderedDict(AA).items()
[('a', 7), ('b', 5), ('c', 1)]

或者如果你不关心效率(或者如果AA很短):

>>> print sorted(dict(AA).items())
[('a', 7), ('b', 5), ('c', 1)]

AA 的结构已经适合用作 dictcollections.OrderedDict 的初始化参数,所以你可以简单地做:

from collections import OrderedDict
BB = OrderedDict(AA).items()

来自评论:

I thought the dict would become limiting, if I would have something like A = [["a", 1, True, .123], ["b", 5, False .123], ["a", 7, True, .537] ], and than want have replacements for the first elements being equal, and the 4th elements being equal and so on.

@TigerhawkT3 的出色解决方案可以轻松扩展以满足该(附加的、新的)要求:

import sys

items = None
if sys.version_info[0] == 3:
    items = lambda d: d.items()
else:    
    items = lambda d: d.iteritems()

AAA = [["a", 1, True, .123], ["b", 5, False, .123], ["a", 7, True, .537]]

def last_unique(arr, key_pos):
    return list(v for k,v in items(dict([aa[key_pos],aa] for aa in arr)))

for key_pos in range(0,4):
    print(last_unique(AAA, key_pos))

输出:

[['a', 7, True, 0.537], ['b', 5, False, 0.123]]
[['a', 1, True, 0.123], ['b', 5, False, 0.123], ['a', 7, True, 0.537]]
[['b', 5, False, 0.123], ['a', 7, True, 0.537]]
[['b', 5, False, 0.123], ['a', 7, True, 0.537]]