检查两个列表是否与Python类型相同

时间:2016-02-22 12:51:25

标签: python python-2.7 types

我想检查两个列表是否对每个索引都有相同类型的项目。例如,如果我有

y = [3, "a"]
x = [5, "b"] 
z = ["b", 5]

Truex的检查应为yFalsey的检查应为z,因为相同位置的元素类型不相等。

6 个答案:

答案 0 :(得分:18)

只需map各自type的元素并进行比较:

>>> x = [5, "b"] 
>>> y = [3, "a"]
>>> z = ["b", 5]
>>> map(type, x) == map(type, y)
True
>>> map(type, x) == map(type, z)
False

对于Python 3,您还必须使用list函数或list comprehensionmap生成器转换为正确的列表:

>>> list(map(type, x)) == list(map(type, y))
True
>>> [type(i) for i in x] == [type(i) for i in z]
False

我做了一些时序分析,将上述解决方案与@timgeb的解决方案进行比较,使用allizip,并在不同位置输入第一个不匹配类型。正如预期的那样,map解决方案所花费的时间对于每个输入几乎完全相同,而all + izip解决方案可以非常快速或采取三倍长,取决于第一个差异的位置。

In [52]: x = [1] * 1000 + ["s"] * 1000
In [53]: y = [2] * 1000 + ["t"] * 1000 # same types as x
In [54]: z = ["u"] * 1000 + [3] * 1000 # difference at first element
In [55]: u = [4] * 2000                # difference after first half
In [56]: %timeit map(type, x) == map(type, y)
10000 loops, best of 3: 129 µs per loop
In [58]: %timeit all(type(i) == type(j) for i, j in izip(x, y))
1000 loops, best of 3: 342 µs per loop
In [59]: %timeit all(type(i) == type(j) for i, j in izip(x, z))
1000000 loops, best of 3: 748 ns per loop
In [60]: %timeit all(type(i) == type(j) for i, j in izip(x, u))
10000 loops, best of 3: 174 µs per loop

答案 1 :(得分:18)

使用all进行懒惰评估:

>>> from itertools import izip
>>> all(type(a) == type(b) for a,b in izip(x,y))
True

在Python 3中使用常规zip,它已经返回了一个生成器。

如果列表的长度不同,请先检查长度。检查长度是一个非常快速的O(1)操作:

>>> len(x) == len(y) and all(type(a) == type(b) for a,b in izip(x,y))
True
>>> x = [5,"b",'foo']
>>> len(x) == len(y) and all(type(a) == type(b) for a,b in izip(x,y))
False

and将进行短路评估,这意味着如果长度不同,甚至不会调用all

答案 2 :(得分:3)

lambda的另一个选择:

>>> x = [5, "b"]
>>> y = [3, "a"]
>>> z = ["b", 5]
>>> g = lambda t: [type(i) for i in t]
>>> g(x) == g(y)
True
>>> g(x) == g(z)
False

答案 3 :(得分:2)

使用生成器表达式时非常简单:

are_equal = all(type(i) == type(j) for i, j in zip(x, y))

在该示例中,xy是您要检查的列表。如果您想要添加的内容:

lists = (x, y)
are_equal = all(len(set(type(j) for j in i)) == 1 for i in zip(*lists))

通过这种方式,您可以更改lists,它仍然可以使用。它的工作原理是set删除所有重复项。对于zip()返回的每个元组,它会创建一组每个项目的类型,并通过查看集合的长度是否为1来检查它们是否相同。

答案 4 :(得分:0)

def equalTypes(list1, list2):
    if len(list1) != len(list2):
        return False
    for index, item in enumerate(list1):
        if type(item) != type(list2[index]):
            return False
    return True

我只是遍历列表(检查它们是否首先具有相同的长度)然后当某些类型不匹配时返回False。最后(没有不匹配)我返回True。

答案 5 :(得分:0)

您可以使用selfoperator.eq保持延迟评估,这样可以在不存储列表副本的情况下为您提供合理的平均时间:

itertools

如果列表长度不同,只需先检查长度是最简单和最快的,但如果要将其合并到逻辑中,可以使用 object 作为 fillvalue In [12]: from itertools import imap, starmap, izip In [13]: %timeit map(type, x) == map(type, y) 10000 loops, best of 3: 182 µs per loop In [14]: %timeit all(type(i) == type(j) for i, j in izip(x, u)) 1000 loops, best of 3: 239 µs per loop In [15]: timeit all(type(i) == type(j) for i, j in izip(x, z)) 1000000 loops, best of 3: 1.02 µs per loop In [16]: %timeit all(type(i) == type(j) for i, j in izip(x, u)) 1000 loops, best of 3: 234 µs per loop In [17]: timeit all(starmap(eq, izip(imap(type, x), imap(type, y)))) 1000 loops, best of 3: 238 µs per loop In [18]: timeit all(starmap(eq, izip(imap(type, x), imap(type, u)))) 10000 loops, best of 3: 120 µs per loop In [19]: timeit all(starmap(eq, izip(imap(type, x), imap(type, z)))) 1000000 loops, best of 3: 901 ns per loop

itertools.izip_longest