从另一个列表中访问列表值

时间:2018-03-17 02:29:21

标签: python

我们现在说我有一个列表:

L = [[1,'JAYCE'],[2,'AMIE'],[3,'JACK'],[4,'STEVE'],[5,'JAYCE']]

我有另一个列表,其中包含按顺序排序的名称:

sortedNames = ['AMIE','JACK','JAYCE','JAYCE','STEVE']

我想得到的输出是,根据排序的名称列表,我想将ID添加回基于sortedNames列表的排序顺序中的名称。

finalist = [[2,'AMIE'],[3,'JACK'],[1,'JAYCE'],[5,'JAYCE'],[4,'STEVE']]

请注意,Jayce出现两次,所以即使Jayce的第一次出现有5次,然后是1次,它也完全没问题。

我一直在想类似的事情:

L = [[1,'JAYCE'],[2,'AMIE'],[3,'JACK'],[4,'STEVE'],[5,'JAYCE']]
sortedNames = ['AMIE','JACK','JAYCE','JAYCE','STEVE']

finalist = []
for i in sortedNames:
    j = 0
    if i in L[j][1]:
        finalist.append(L[0] + i)
    j+=1

print(finalist)

我收到错误说:

TypeError: can only concatenate list (not "str") to list

我肯定认错了。

3 个答案:

答案 0 :(得分:1)

因此,只要您的数据表现良好,您就可以使用defaultdict将数字分组为deques:

In [14]: from collections import defaultdict, deque

In [15]: grouper = defaultdict(deque)

In [16]: for a,b in L:
    ...:     grouper[b].append(a)
    ...:

然后简单地说:

In [17]: grouper
Out[17]:
defaultdict(collections.deque,
            {'AMIE': deque([2]),
             'JACK': deque([3]),
             'JAYCE': deque([1, 5]),
             'STEVE': deque([4])})

In [18]: [[grouper[x].popleft(), x] for x in sortedNames]
Out[18]: [[2, 'AMIE'], [3, 'JACK'], [1, 'JAYCE'], [5, 'JAYCE'], [4, 'STEVE']]

我意识到在列表理解中使用pop是一个丑陋的蠢...

以下是仅使用dictlist的方法:

In [19]: grouper = {}
    ...: for a,b in L:
    ...:     grouper.setdefault(b, []).append(a)
    ...:

In [20]: grouper = {k:v[::-1] for k, v in grouper.items()}

In [21]: [[grouper[x].pop(), x] for x in sortedNames]
Out[21]: [[2, 'AMIE'], [3, 'JACK'], [1, 'JAYCE'], [5, 'JAYCE'], [4, 'STEVE']]

两种方法都是O(N)。

编辑

我刚刚意识到你真正想要的不是生成排序名称列表,只需使用密钥排序L直接:

In [26]: L
Out[26]: [[1, 'JAYCE'], [2, 'AMIE'], [3, 'JACK'], [4, 'STEVE'], [5, 'JAYCE']]

In [27]: from operator import itemgetter

In [28]: sorted(L, key=itemgetter(1))
Out[28]: [[2, 'AMIE'], [3, 'JACK'], [1, 'JAYCE'], [5, 'JAYCE'], [4, 'STEVE']]

答案 1 :(得分:1)

您可以使用sorted()函数执行此操作,并使用其key参数查找存储名称的位置:

finalList = sorted(L, key=lambda x: sortedNames.index(x[1]))

结果是:

[[2, 'AMIE'], [3, 'JACK'], [1, 'JAYCE'], [5, 'JAYCE'], [4, 'STEVE']]

答案 2 :(得分:0)

您可以通过将每个名称分组到为该名称找到的所有ID的列表来创建字典。然后,可以应用next

import itertools
L = [[1,'JAYCE'],[2,'AMIE'],[3,'JACK'],[4,'STEVE'],[5,'JAYCE']]
new_l = {a:iter([c for c, _ in b]) for a, b in itertools.groupby(sorted(L, key=lambda x:x[-1]), key=lambda x:x[-1])}
sortedNames = ['AMIE','JACK','JAYCE','JAYCE','STEVE']
final_data = [[next(new_l[i]), i] for i in sortedNames]

输出:

[[2, 'AMIE'], [3, 'JACK'], [1, 'JAYCE'], [5, 'JAYCE'], [4, 'STEVE']]

修改

也可以使用sorted

L = [[1,'JAYCE'],[2,'AMIE'],[3,'JACK'],[4,'STEVE'],[5,'JAYCE']]
sortedNames = ['AMIE','JACK','JAYCE','JAYCE','STEVE']
new_result = sorted(L, key=lambda x:(sortedNames.index(x[-1]), x[0]))

输出:

[[2, 'AMIE'], [3, 'JACK'], [1, 'JAYCE'], [5, 'JAYCE'], [4, 'STEVE']]