我正在尝试找到比较两个二维数组并编写第一个数组中没有的元素的最佳方法。
对于一维数组,一切都很简单:
select to_char('_due', 'MM/DD/YYYY') from moments;
ERROR: function to_char(unknown, unknown) is not unique
LINE 1: select to_char('_due', 'MM/DD/YYYY') from moments;
^
HINT: Could not choose a best candidate function. You might need to add explicit type casts.
_id | _cid | _created | _due
-----+------+------------+------------
1 | 6 | 2018-08-14 | 2018-08-22
在这种情况下将为a = [1, 2]
b = [1, 2, 3]
newArray = list(set(b) - set(a))
在这种情况下很难。例如,我有:
newArray
我想获得[3]
,但是如果我尝试a = [[1, 2, 3], [1, 2, 5], [4, 6, 9]]
b = [[1, 2, 3], [1, 4, 5], [2, 6, 5]]
会导致错误
newArray = [[1, 4, 5], [2, 6, 5]]
如何实现与一维数组相同的效果?数组的长度可能不同。
答案 0 :(得分:2)
您必须将列表转换为可哈希的格式,例如tuple
:
>>> a = [[1, 2, 3], [1, 2, 5], [4, 6, 9]]
>>> b = [[1, 2, 3], [1, 4, 5], [2, 6, 5]]
>>> set(map(tuple, b)) - set(map(tuple, a))
set([(2, 6, 5), (1, 4, 5)])
如果结果应为列表列表,则可以随后将元组转换回去。
>>> list(map(list, set(map(tuple, b)) - set(map(tuple, a))))
[[2, 6, 5], [1, 4, 5]]
与您的原始方法一样,它的复杂度为O(n + m),n和m为列表的长度,这使其比嵌套列表理解要快一些,后者使用在列表中重复查找的嵌套列表理解为O(n ),而不是使用O(1)在集合中进行查找,但是它还带来了一些转换为元组,创建集合等的开销。它的实际上是否更快,以及是否值得更复杂代码,可能取决于列表的大小。
如果列表很短,例如10个元素,实际上列表理解比使用map
和set
快一点,而 quitet 比使用map
和{{1}快一点}并转换回set
:
list
但是,如果列表较长,比如说有1000个元素,那么使用>>> a = [[randint(0, 3) for _ in range(3)] for _ in range(10)]
>>> b = [[randint(0, 3) for _ in range(3)] for _ in range(10)]
>>> %timeit [x for x in b if x not in a]
100000 loops, best of 3: 13.8 us per loop
>>> %timeit set(map(tuple, b)) - set(map(tuple, a))
100000 loops, best of 3: 14 us per loop
>>> %timeit list(map(list, set(map(tuple, b)) - set(map(tuple, a))))
10000 loops, best of 3: 21.8 us per loop
就会变得更快。
set
答案 1 :(得分:1)
您可以使用列表推导来遍历b
并返回不在a
中的列表。这是一个示例:
a = [[1, 2, 3], [1, 2, 5], [4, 6, 9]]
b = [[1, 2, 3], [1, 4, 5], [2, 6, 5]]
new_array = [x for x in b if x not in a]
new_array
等于:
[[1, 4, 5], [2, 6, 5]]