我有一个多维可迭代的a
,我需要找出a
的哪些元素以b
作为其第一运算符。现在,我使用[i for i in a if i[0] == b]
,但是如果a
真的很长,那就太慢了。有更快或更简单的替代方法吗?
示例:a = [[5, 8], [6, 7], [5, 4], [8, 5]]
,b = 5
,预期收益为[[5, 8], [5, 4]]
答案 0 :(得分:1)
一种方法是使用numpy数组,例如:
In [21]: import numpy as np
In [22]: l = np.random.randint(1,10,size=(5000,2))
In [23]: %timeit [i for i in l if i[0] == 5]
1.9 ms ± 49.2 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
In [24]: %timeit l[l[:,0] == 5]
26.9 µs ± 60 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
以及有关您的数据示例:
In [25]: a = np.array([[5, 8], [6, 7], [5, 4], [8, 5]])
...: b = 5
In [26]: a[a[:,0] == b]
Out[26]:
array([[5, 8],
[5, 4]])
答案 1 :(得分:1)
在一个未知长度的可迭代对象的一般情况下,我不知道一种更快的方法。问题的症结在于Python速度慢,因此检查每个可迭代项的第一项是否相等的最快方法是避免在Python中进行。根据数据的结构,这里有几种使用NumPy加速这些比较的方法(其内部是在C中实现的,而不是在Python中实现的。)
...如果所有内部可迭代对象的长度都相同,并且所有元素都是相同的类型。
例如,如果您有
some_list = [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]]
您可以将其格式化为numpy数组,然后执行np.array(some_list)[:, 0]
(或者,更好的做法是np.array(some_list, order="F")[0, :]
,因为numpy数组默认情况下具有主要行存储顺序)。
...如果第一个元素具有特殊状态。
也许您可以创建一个新对象来容纳可迭代对象而不是列表。例如,代替
people_list = [['Bruce', 1, 2, 3], ['Sharon', 7, 3, 2, 3, 2], ['Lee', 3]]
您可以创建一个新对象
class People:
def __init__(self, names, data):
assert len(names) == len(data)
self.names = np.asarray(names) # A vector of names
self.data = data
def get_person_data_by_name(self, name):
person_matches = np.where(self.names == names)[0]
if len(person_matches) == 0:
retrieved_data = None
elif len(person_matches) == 1:
retrieved_data = self.data[person_matches[0]]
else:
raise RuntimeError("Multiple people with that name.")
return retrieved_data
people = People(['Bruce', 'Sharon', 'Lee'], [[1, 2, 3], [7, 3, 2, 7, 2], [3]])
这消除了所有可迭代项必须具有相同长度的限制,但对数据施加了其他限制。