令人惊讶的python集合组合方法

时间:2016-11-04 06:22:31

标签: python hashmap

我知道python中的set()没有订单,因为它是作为哈希表实现的。但是,使用set.intersection()来解决涉及订单的问题我感到有点意外。

所以我给了两个带有命令的列表,例如,表示一些排名或发生的顺序。我必须找到两个列表共有的元素,并且在两个列表中具有最高顺序(出现在第一个中)。例如,

List1 = ['j','s','l','p','t']
List2 = ['b','d','q','s','y','j']

应输出's',因为它是List1中的第二位,并且出现在List2中的第一位。

如果您将每个列表转换为集合并进行交集Set1.intersection(Set2),则会得到一个集合set(['s', 'j'])。在我的情况下,我可以将其转换为列表并吐出第一个元素,这大约是O(n1 + n2)。

我很乐意解决这个面试问题(所有测试都通过了),但我很惊讶我怎样才能使用python set来解决这样一个基于订单的问题。

有没有人知道这是如何运作的?有什么可能的情况,这可能会崩溃?

编辑:这似乎就像是一个好运的案例,所以如果你有一个很好的解决方案来解决这个问题,也会受到赞赏

2 个答案:

答案 0 :(得分:1)

我找到了O(n1+n2)方法。注释代码如下。诀窍是创建一个查找表(不是字典,一个简单的数组)来索引两个列表中字母的最小位置,然后找到这些位置和相关字母之和的最小值。

List1 = ['j','s','l','p','t']
List2 = ['b','d','q','s','y','j']

# unreachable max value to initialize the slots
maxlen = max(len(List1),len(List2))+1000

# create empty slot_array (initialized to values higher than last letter pos
# for both lists (the value is greater than any "valid" position)
# first pos (index 0) is for letter "a", last pos is for letter "z"

slot_array = [[maxlen,maxlen] for x in range(ord('a'),ord('z')+1)]

# scan both lists, and update the position if lower than the one in slot_array
for list_index,the_list in enumerate((List1,List2)):
    print(list_index)
    for letter_index,letter in enumerate(the_list):
        slot = slot_array[ord(letter)-ord('a')]
        if slot[list_index]>letter_index:
            slot[list_index] = letter_index

# now compute minimum of sum of both minimum positions for each letter
min_value = maxlen*2

for i,(a,b) in enumerate(slot_array):
    sab = a+b
    if sab < min_value:
        min_value = sab
        min_index = i

# result is the letter with the minimal sum
print(chr(min_index+ord('a')))

答案 1 :(得分:0)

列表理解可以完成这项工作:

Set2 = set(List2)
[x for x in List1 if x in Set2]

这将保持List1的顺序,您也可以对List2执行相同的操作。

然后,你可以在列表理解上调用next(或者生成器更有效率)来获得第一场比赛。