我有2个不同的列表:
l1 = ['a','b','a','e','b','c','a','d']
l2 = ['t1','t2','t3','t4','t5','t6','t7','t8']
l1
和l2
的长度将始终相同。它们实际上是逻辑映射-l1
中的每个项目都对应于l2
中的值。
我想确定l1
中的不同元素。我使用set
和list comprehension
进行了如下操作:
used = set()
distl1 = [x for x in l1 if x not in used and (used.add(x) or True)]
在这里,输出将是:
distl1 = ['a','b','e','c','d']
这不过是每个不同元素的首次出现。
现在,如何构建列表distl2
,以便将输出作为l2
中与第一次出现的值(即distl1
)相对应的值得到?
distl2 = ['t1','t2','t4','t6','t8']
答案 0 :(得分:3)
我的想法是使用OrderedDict
建立对应于l1
和l2
元素的(键,值)对的映射,然后提取values
从该字典作为列表。
>>> from collections import OrderedDict
>>>
>>> l1 = ['a','b','a','e','d','c','a','b']
>>> l2 = ['t1','t2','t3','t4','t5','t6','t7','t8']
>>>
>>> d = OrderedDict()
>>> for k, v in zip(l1, l2):
...: if k not in d: # <--- check if this key has already been seen!
...: d[k] = v
...:
>>> distl2 = list(d.values())
>>> distl2
>>> ['t1', 't2', 't4', 't5', 't6']
Python 3.7+用户注意事项:保证常规字典会记住其键插入顺序,因此您可以省略导入OrderedDict
。
答案 1 :(得分:2)
您也可以这样做:
distl2 = [l2[l1.index(key)] for key in distl1]
答案 2 :(得分:2)
字典在Python 3.6+中排序,作为3.6中的实现细节,并在3.7+中得到确认。因此,在这种情况下,您可以将dict
与可迭代项一起使用,从而忽略重复项。要忽略重复项,可以使用itertools
unique_everseen
recipe,也可以通过第三方more_itertools.unique_everseen
或toolz.unique
使用:
from operator import itemgetter
from toolz import unique
l1 = ['a','b','a','e','b','c','a','d']
l2 = ['t1','t2','t3','t4','t5','t6','t7','t8']
keys, values = zip(*dict(unique(zip(l1, l2), key=itemgetter(0))).items())
print(keys)
('a', 'b', 'e', 'c', 'd')
print(values)
('t1', 't2', 't4', 't6', 't8')
对于不按字典排序的Python 2.7,可以使用collections.OrderedDict
代替dict
:
from collections import OrderedDict
keys, values = zip(*OrderedDict(unique(zip(l1, l2), key=itemgetter(0))).items())
答案 3 :(得分:1)
问题并没有说明您是否需要保留订单。否则,l1
的唯一值列表将为:
distl1 = list(set(l1))
以及l2
的对应值:
distl2 = [l2[l1.index(value)] for value in distl1]
(其中index()
总是返回第一个匹配项)
结果列表将按照随机顺序保留您的逻辑映射:
['b', 'e', 'c', 'd', 'a']
['t2', 't4', 't6', 't8', 't1']
编辑:
另一种方法(无字典,无index()
循环,保留顺序,友好2.7):
l1 = ['a','b','a','e','b','c','a','d']
l2 = ['t1','t2','t3','t4','t5','t6','t7','t8']
distl1 = []
distl2 = []
for i, val in enumerate(l1):
if val not in distl1:
distl1.append(val)
distl2.append(l2[i])