获取新的唯一列表,仅包含原始列表中最后出现的元素
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
的结构已经适合用作 dict
或 collections.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]]
对不起,我真的不知道如何命名我的问题。我正在寻找解决以下问题的 '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
的结构已经适合用作 dict
或 collections.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]]