【问题标题】:Rotating list based on matching elements of a different list基于不同列表的匹配元素的轮换列表
【发布时间】:2020-08-28 16:37:04
【问题描述】:

假设我有两个列表: 列表1

[26, 45, 15]

列表2

[13, 15, 20]

假设两个列表之间总是有一个完全相同的元素,我将如何将 list2 重新排序为:

[20, 13, 15]

其中 15 成为 list2 的第三个元素,因为 15 是 list1 的第三个元素(同时保持 13、15、然后 20 的顺序)?我尝试过这样的事情:

# Reorder list2 to correspond with list1
key = 0
newOrder = []
for i in range(3):
   for j in range(3):
            if list2[i] == list1[j]:  # if elements 
                key = i - j
for k in range(3):
   index = k + key
   if index == 3:
            index = 0
   if index == -1:
            index = 2
   newOrder.append(list2[index])

但它没有 100% 的成功率。

【问题讨论】:

  • "(保留数字序列的同时)" 那不应该是[13, 20, 15]吗?还是您的意思是要“旋转”列表,直到匹配的元素出现在正确的位置?
  • 虽然没有保留序列
  • @tobias_k 我应该说得更清楚。顺序保持不变(总是按照 13、15、20 的顺序)
  • 我无法理解这一点。:While the order of 13, 15, and then 20 is kept

标签: python


【解决方案1】:

假设您要旋转list2,以便“共享”元素与list1 中的位置相同。

首先,要获得匹配的索引,您不必比较所有元素。相反,您可以使用 dict 来存储哪个元素在哪个位置,然后通过 list2 单次获取匹配位置(如果列表始终只有 3 个元素,这无关紧要,但对于更长的列表,它会减少从 O(n²) 到 O(n)) 的复杂度

list1 = [26, 45, 15]
list2 = [13, 15, 20]
pos2 = {x: i for i, x in enumerate(list2)}
p1, p2 = next((i, pos2[x]) for i, x in enumerate(list1) if x in pos2)

然后,您可以使用列表推导式从 list2 获取“旋转”元素,使用模 % 在索引大于列表长度时“环绕”。

n = len(list2)
res = [list2[(i+p2-p1) % n] for i in range(n)]
print(res) # [20, 13, 15]

【讨论】:

    【解决方案2】:

    此代码获取 list1 中也存在于 list2 中的数字的值和索引。

    list1 = [26, 45, 15]
    list2 = [13, 15, 20]
    
    index, number = next((idx,number) for idx, number in enumerate(list1) if number in list2)
    

    然后它从 list2 中删除数字并再次将其插入到想要的索引处:

    list2.remove(number)
    list2.insert(index,number)
    
    print(list2)
    

    输出将是

    [13, 20, 15]
    

    【讨论】:

    • 我认为他希望订单保持不变
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-02-12
    • 1970-01-01
    • 2018-10-21
    • 2018-04-15
    • 2022-10-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多