我在 Python 中有一个词典列表。列表的每个元素都有一个type
键,其中包含元素的类型。像这样:
e1 = {"type": 1, "value": 23.1}
e2 = {"type": 1, "value": 21.1}
e3 = {"type": 2, "value": -10.1}
e4 = {"type": 1, "value": -2.59}
l = [e1, e2, e3, e4]
我想知道列表l
中的所有元素是否都是相同的type
。
我有这个:
def same_type(l):
return l[0].type == l[1].type == l[2].type == l[3].type
假设列表总是大小相同,是否有更多的pythonic方法呢?
答案 0 :(得分:8)
首先出现在我的脑海中:
all(e['type'] == L[0]['type'] for e in L)
类型集的长度:
len(set(e['type'] for e in L)) == 1
比使用生成器的all
更有效,但没有列表:
>>> %timeit all(e['type'] == l[0]['type'] for e in l)
1000000 loops, best of 3: 784 ns per loop
>>> %timeit len(set(e['type'] for e in l)) == 1
1000000 loops, best of 3: 676 ns per loop
>>> %timeit all([e['type'] == l[0]['type'] for e in l])
1000000 loops, best of 3: 602 ns per loop
使用缓存l[0]['type']
:
>>> t1 = l[0]['type']
>>> %timeit all([e['type'] == t1 for e in l])
1000000 loops, best of 3: 447 ns per loop
>>> %timeit all(e['type'] == t1 for e in l)
1000000 loops, best of 3: 655 ns per loop
带有list-comp的 set
比使用genexpr更慢:
>>> %timeit len(set([gettype(e) for e in l])) == 1
1000000 loops, best of 3: 735 ns per loop
当没有可能发生短路的时候,我想到了另一种比set
更快的方式:
>>> %timeit [e['type'] for e in l].count(t1) == len(l)
1000000 loops, best of 3: 421 ns per loop
另一个编辑:显然最直接的方法是最快:
In [31]: def same_type(L):
....: t1 = L[0]['type']
....: for e in L:
....: if e['type'] != t1:
....: return False
....: return True
....:
In [32]: %timeit same_type(l)
1000000 loops, best of 3: 352 ns per loop
具有相同类型的长输入(无短路)
In [47]: l = [{'type': 1} for _ in range(1000)]
In [48]: %timeit same_type(l)
10000 loops, best of 3: 37.6 us per loop
In [49]: %timeit all(e['type'] == l[0]['type'] for e in l)
10000 loops, best of 3: 112 us per loop
In [50]: %timeit all([e['type'] == l[0]['type'] for e in l])
10000 loops, best of 3: 103 us per loop
In [51]: %timeit len(set(e['type'] for e in l)) == 1
10000 loops, best of 3: 63.3 us per loop
长输入不同类型(立即短路)
In [40]: l = [{'type': x} for x in range(1000)]
In [43]: %timeit same_type(l)
1000000 loops, best of 3: 337 ns per loop
In [44]: %timeit all(e['type'] == l[0]['type'] for e in l)
1000000 loops, best of 3: 656 ns per loop
In [45]: %timeit all([e['type'] == l[0]['type'] for e in l])
10000 loops, best of 3: 99.4 us per loop
In [46]: %timeit len(set(e['type'] for e in l)) == 1
10000 loops, best of 3: 68.6 us per loop
答案 1 :(得分:5)
使用set()
收集所有类型,然后测试它是否为长度1:
def same_type(L):
if not L: return True # empty list case
return len(set(d['type'] for d in L)) == 1
这必须扫描所有元素。您还可以与第一个元素进行比较,此时您只需要进行足够的测试以找到不匹配的元素:
def same_type(L):
if not L: return True # empty list case
t = L[0]['type']
return all(t == d['type'] for d in L)
对于较小的输入,set()
方法更快,但对于较大输入,第二种形式可以超越set()
方法在输入中有第二种类型是足够大的。
答案 2 :(得分:4)
适用于任何长度的lst
:
def same_type(lst):
return all(d['type'] == lst[0]['type'] for d in lst[1:])
与len(set(...)) == 1
相比,速度更快,因为只要找到不同的type
,它就会停止。