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

时间:2015-11-27 13:10:09

标签: python list dictionary replace set

我很抱歉,但我真的不知道如何命名我的问题。我正在寻找解决以下问题的“最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的问题在于,如果列表元素变得更复杂,它可能变得有限,并且可能会对替换有一些额外的限制(即某些值比要替换的元素的值更大/更小) 。)

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

5 个答案:

答案 0 :(得分:3)

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

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

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

答案 1 :(得分:1)

由于新密钥:对字典的值分配将自动覆盖旧字典,因此答案就像dict()一样简单:

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

答案 2 :(得分: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)]

答案 3 :(得分:1)

AA的结构已经适合用作dictcollections.OrderedDict的初始化参数,因此您可以这样做:

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

答案 4 :(得分:1)

来自评论:

  

我认为如果我愿意的话,dict会变得有限   比如A = [[" a",1,True,.123],[" b",5,False .123],[" a",7 ,是的,   .537]],而不是想要替换第一个元素   相等,第四个元素相等,等等。

@ 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]]