我想检查两个列表在每个索引处的项是否具有相同的类型。例如,如果我有
y = [3, "a"]
x = [5, "b"]
z = ["b", 5]
对于x
和y
,检查结果应为True
。
对于y
和z
,检查结果应为False
,因为相同位置的元素类型不相等。
我想检查两个列表在每个索引处的项是否具有相同的类型。例如,如果我有
y = [3, "a"]
x = [5, "b"]
z = ["b", 5]
对于x
和y
,检查结果应为True
。
对于y
和z
,检查结果应为False
,因为相同位置的元素类型不相等。
>>> 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,您还需要将map
生成器转换为适当的列表,可以使用list
函数或使用列表推导式:
>>> 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
使用 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
< p >如果长度不同,and
将进行短路评估,这意味着all
甚至不会被调用。itertools.izip_longest
代替? - tobias_kitertools
。 对我来说,元组列表并不比生成器更糟糕。 - zondoizip_longest
,但你会用什么作为填充值,以避免它成为列表元素?我认为在这里事先检查长度更好。 - timgebx = [1, 2, 3]
和 y = ['foo', 2, 3]
,只需要第一个元组。 - timgebizip
,我解释了一下。 :) - timgeb使用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
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。x
和 z
为 true
。 - tobias_kset(type(j) for j in i))
会给出当前zip元组中每个元素类型的集合。如果该集合的长度不为1,则其中一个元素与其他元素的类型不同。我已经测试过它,看起来它是有效的。我是否漏掉了什么? - zondodef 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。
你可以使用 itertools
和 operator.eq
来保持惰性求值,这样可以在不存储列表副本的情况下获得相当不错的平均时间:
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
并将object作为fillvalue:all(starmap(eq, izip_longest(imap(type, x), imap(type, y), fillvalue=object()))
itertools.izip_longest
才能使其适用于长度不相等的列表,而且在我看来,这只会使代码更加复杂(除非列表特别长)。 - tobias_k