我想检查两个列表是否对每个索引都有相同类型的项目。例如,如果我有
y = [3, "a"]
x = [5, "b"]
z = ["b", 5]
True
和x
的检查应为y
。
False
和y
的检查应为z
,因为相同位置的元素类型不相等。
答案 0 :(得分:18)
>>> 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 comprehension将map
生成器转换为正确的列表:
>>> list(map(type, x)) == list(map(type, y))
True
>>> [type(i) for i in x] == [type(i) for i in z]
False
我做了一些时序分析,将上述解决方案与@timgeb的解决方案进行比较,使用all
和izip
,并在不同位置输入第一个不匹配类型。正如预期的那样,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))
在该示例中,x
和y
是您要检查的列表。如果您想要添加的内容:
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)
您可以使用self
与operator.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