识别列表中的不同元素并将其映射到python中另一个列表中的对应索引

时间:2018-11-13 10:28:34

标签: python python-2.7

我有2个不同的列表:

l1 = ['a','b','a','e','b','c','a','d']
l2 = ['t1','t2','t3','t4','t5','t6','t7','t8']

l1l2的长度将始终相同。它们实际上是逻辑映射-l1中的每个项目都对应于l2中的值。

我想确定l1中的不同元素。我使用setlist 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']

4 个答案:

答案 0 :(得分:3)

我的想法是使用OrderedDict建立对应于l1l2元素的(键,值)对的映射,然后提取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 +

字典在Python 3.6+中排序,作为3.6中的实现细节,并在3.7+中得到确认。因此,在这种情况下,您可以将dict与可迭代项一起使用,从而忽略重复项。要忽略重复项,可以使用itertools unique_everseen recipe,也可以通过第三方more_itertools.unique_everseentoolz.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

对于不按字典排序的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])