我有两个列表,比如说listOne = ['a','b','c']
和listTwo = [['d'], ['e'], ['f']]
我还有一个函数MyFunction
,它接受listOne
参数并根据一堆条件重新排列它,然后返回它。
所以现在我有了listOne = ['b','a','c']
,我在这里想要实现的是我listTwo
也想准确地安排如何listOne
重新安排。
所以我的 listTwo 最终会是listTwo = [['e'], ['d'], ['f']]
我知道这可以通过loop
orif
语句来实现,但是是否有任何内置函数或者可能是一段非常有效的代码可以在短时间内实现此目的,而无需使用许多步骤?
如果值是唯一的,您可以在转换 listOne 之前构建 listOne 和 listTwo 之间的映射字典。然后使用字典重新组织 listTwo
mapping = dict(zip(listOne,listTwo))
listOne = myFunction(listOne)
listTwo = [mapping[n] for n in listOne]
Run Code Online (Sandbox Code Playgroud)
请注意,listOne 的值必须是可散列的才能起作用
您甚至可以使用额外的 zip 将其扩展到更多列表:
mapping = dict(zip(listOne,zip(listTwo,listThree,listFour)))
listOne = myFunction(listOne)
listTwo,listThree,listFour = map(list,zip(*map(mapping.get,listOne)))
Run Code Online (Sandbox Code Playgroud)
如果将 myFunction 应用于 listOne 时 listTwo 尚不可用,则可以在映射字典中保存索引而不是值。然后您可以将索引应用于 listTwo (以及任何其他列表):
indexMap = {n:i for i,n in enumerate(listOne)}
listOne = myFunction(listOne)
listTwo = [listTwo[indexMap[n]] for n in listOne]
listThree = [listThree[indexMap[n]] for n in listOne]
listFour = [listFour[indexMap[n]] for n in listOne]
Run Code Online (Sandbox Code Playgroud)
如果列表可以包含重复值,则需要集合模块的一些帮助,以便映射字典可以为 listOne 的每个不同项(成为字典的键)包含 listTwo 的多个值:
from collections import deque,defaultdict
listOne = ['a','b','c','b']
listTwo = [['d'], ['e'], ['f'],['g']]
mapping = defaultdict(deque)
for o,t in zip(listOne,listTwo): mapping[o].append(t)
listOne = ['b','b','c','a']
listTwo = [d.popleft() for d in map(mapping.get,listOne)]
print(listTwo)
[['e'], ['g'], ['f'], ['d']]
Run Code Online (Sandbox Code Playgroud)
或使用索引:
indexMap = defaultdict(deque)
for i,o in enumerate(listOne): indexMap[o].append(i)
listOne = ['b','b','c','a']
listTwo = [listTwo[d.rotate() or d[-1]] for d in map(indexMap.get,listOne)]
Run Code Online (Sandbox Code Playgroud)
这也可以在没有集合模块的情况下完成,但 defaultdict 更方便(比 dict)并且 deque 更高效(比 list)。