在保留顺序的同时,通过键将python列表分解为子列表的最有效方法
第一次在这里张贴海报。如果我有一个包含具有不同信息的子列表的列表,并且我想将具有相同键值的所有子列表分组到一个新的子列表中(例如,根据键值创建一个列表),那么最有效的方法是什么 例如:在保留顺序的同时,通过键将python列表分解为子列表的最有效方法,python,list,Python,List,第一次在这里张贴海报。如果我有一个包含具有不同信息的子列表的列表,并且我想将具有相同键值的所有子列表分组到一个新的子列表中(例如,根据键值创建一个列表),那么最有效的方法是什么 例如: A = [[1,2,3], [1,3,7], [2,1,3], [8,9,6], [3,7,9], [2,3,8], [1,2,4]] 我想将“0”索引中具有相同项的所有子列表分组到一个新的子列表中,最好保留原始顺序: B = [ [[1,2,3], [1,3,7], [1,2,4]], [[2,1,3],[2
A = [[1,2,3], [1,3,7], [2,1,3], [8,9,6], [3,7,9], [2,3,8], [1,2,4]]
我想将“0”索引中具有相同项的所有子列表分组到一个新的子列表中,最好保留原始顺序:
B = [ [[1,2,3], [1,3,7], [1,2,4]], [[2,1,3],[2,3,8]], [[8,9,6]], [[3,7,9]] ]
我已经多次解决了这个问题,但我想看看是否有更有效的方法来解决这个问题。是的,出于这个原因,我可能会使用numpy包,但我对列表解决方案感兴趣
通常,我会首先在每个子列表的第一个索引中唯一化该项(如果我不担心效率或顺序,则使用set方法),然后在整个列表上循环,将子列表合并到一个新的子列表中:
def getUniqueList(list):
seen = []
for e in list:
if e not in seen:
seen.append(e)
return seen
def uniquify(list):
# Get all items from the first column
new_list = [item[0] for item in list]
return getUniqueList(new_list)
def rearrangeList(A, A_0):
B = []
for i in range(len(A_0)):
B.append([])
for i in range(len(A)):
index = A_0.index(A[i][0])
B[index].append(A[i])
return B
A = [[1,2,3], [1,3,7], [2,1,3], [8,9,6], [3,7,9], [2,3,8], [1,2,4]]
A_0 = uniquify(A) # Contains all unique keys in index 0 of list A
B = rearrangeList(A, A_0)
print(B)
这应该(我没有测试它,但我会这样编码)导致:
B=[[1,2,3],[1,3,7],[1,2,4],[2,1,3],[2,3,8],[8,9,6],[3,7,9]]
我想知道1)是否有更好的方法来提高效率,2)是否有一种方法可以减少步骤(不一定是有效的,只是好奇)。希望这个问题提出得很好,但如果需要编辑,请告诉我 本质上,您需要一个分组操作。使用字典按键分组,使用OrderedDict保持顺序:
>>> from collections import OrderedDict
>>> groups = OrderedDict()
>>> A = [[1,2,3], [1,3,7], [2,1,3], [8,9,6], [3,7,9], [2,3,8], [1,2,4]]
>>> key = lambda l: l[0]
>>> for sub in A:
... groups.setdefault(key(sub),[]).append(sub)
...
>>> groups
OrderedDict([(1, [[1, 2, 3], [1, 3, 7], [1, 2, 4]]), (2, [[2, 1, 3], [2, 3, 8]]), (8, [[8, 9, 6]]), (3, [[3, 7, 9]])])
>>> B = list(groups.values())
>>> B
[[[1, 2, 3], [1, 3, 7], [1, 2, 4]], [[2, 1, 3], [2, 3, 8]], [[8, 9, 6]], [[3, 7, 9]]]
一种老派(但又好又简单)的方法:
A = [[1,2,3], [1,3,7], [2,1,3], [8,9,6], [3,7,9], [2,3,8], [1,2,4]]
A = sorted(A, key=lambda x: x[0]) #sort just by the first index to preserve order
B = [[A[0]]]
for list in A[1:]: # add to the last list or create new one
if B[-1][-1][0]==list[0]: #
B[-1].append(list) #
else: #
B.append([list]) #
B
#output:
[[[1, 2, 3], [1, 3, 7], [1, 2, 4]], [[2, 1, 3], [2, 3, 8]], [[3, 7, 9]], [[8, 9, 6]]]
保持原始列表顺序的要求很有趣 假设您的列表是
A
,并且希望在B
中得到结果,则以下代码在使用输入时构造列表,因此保留列表的原始顺序:
from collections import defaultdict
B=[]
reduce(lambda a,n: a[n[0]].append(n) or a,A,defaultdict(lambda: B.append([]) or B[-1]))
或者,以下更简单的代码在defaultdict内创建列表,然后进行复制,但原始列表的顺序丢失:
from collections import defaultdict
B=reduce(lambda a,n: a[n[0]].append(n) or a,A,defaultdict(list)).values()
请注意,子列表将按其最初出现的顺序排列。建议改进工作代码的最佳人选将是使用而不是stackoverflow。保留组的顺序使此问题不同于简单的分组问题。请注意,将
排序的添加到结果列表中并不会按照问题中的要求创建排序。@Tadhgmald Jensen,谢谢,我下次会尝试!为什么不B=list(groups.values())
?@Copperfield噢,我只是太傻了。@juanpa.arrivillaga,这帮了大忙,谢谢!