优化:删除列表列表之间的差异
Optimization: Remove difference between list of list
我需要知道我是否可以优化我的代码,因为我觉得可以。
这里是上下文:
list1 = [[1,'name1'], [2,'name2'], [3,'name3']]
list2 = [2,3]
for item in list1:
if item[0] not in list2:
list1.remove(item)
要获取 list1,我正在这样做:
list(filter(lambda x: name in x[1].lower(), list_of_items))
所以我想问一下是否真的可以优化这段代码?
更新:
正如我所问,我不能在 lmbda 过滤器中直接使用 list2,因为我正在使用它:
list2 = set(item[0] for item in list1) - set(object.id for object in list_in_my_bdd)
您可以改用列表推导式,只包含第一个元素在 list2
:
中的 list1
的子列表
[item for item in list1 if item[0] in list2]
列表理解和集合怎么样?
list1 = [[1,'name1'], [2,'name2'], [3,'name3']]
good = {2,3}
print([[a,b] for a,b in list1 if a in good])
# [[2, 'name2'], [3, 'name3']]
你可以这样做。请注意,变量名称与您的问题相同,但 list2 实际上是一个集合(为了提高效率)。
list1 = [[1,'name1'], [2,'name2'], [3,'name3']]
list2 = {2, 3}
list3 = [item for item in list1 if item[0] in list2]
print(list3)
这看起来很像字典查找的工作,它可能比 O(N^2) 列表比较更快。因此,如果您想要 list1
的所有条目,其键包含在 list2
中,并且可以假设 list_of_items
中的键是唯一的,您可以这样做:
list1 = [[1,'name1'], [2,'name2'], [3,'name3']]
dict1 = dict(list1)
list2 = [2,3]
result = [dict1[k] for k in list2]
这要求列表 2 中包含的所有键实际上都在列表 1 中。否则result
里面会有None
个值
时间:
要在笔记本中重现计时:
import numpy as np
list1 = [[i, f"name{i}"] for i in range(10000)]
list2 = np.random.choice(range(10000), 1000).tolist()
dict1 = dict(list1)
%timeit [dict1.get(k) for k in list2]
%timeit [item for item in list1 if item[0] in list2]
>>>10000 loops, best of 5: 141 µs per loop
>>>10 loops, best of 5: 160 ms per loop
所以字典查找比列表理解快大约 1000 倍。
正如@Paul 提到的那样,如果可以直接使用字典替换 list1
的设置,这只会更快:
import numpy as np
list_of_items = [(j, f"name{i}") for j, i in enumerate(np.random.randint(0, 50000, 10000))]
list1 = list(filter(lambda x: "name" in x[1].lower(), list_of_items))
dict1 = dict(filter(lambda x: "name" in x[1].lower(), list_of_items))
To get list1 i'm doing this:
list(filter(lambda x: name in x[1].lower(), list_of_items))
你为什么不把支票也包括在这里:
list(filter(lambda x: name in x[1].lower() and x[0] in list2, list_of_items))
我需要知道我是否可以优化我的代码,因为我觉得可以。
这里是上下文:
list1 = [[1,'name1'], [2,'name2'], [3,'name3']]
list2 = [2,3]
for item in list1:
if item[0] not in list2:
list1.remove(item)
要获取 list1,我正在这样做:
list(filter(lambda x: name in x[1].lower(), list_of_items))
所以我想问一下是否真的可以优化这段代码?
更新:
正如我所问,我不能在 lmbda 过滤器中直接使用 list2,因为我正在使用它:
list2 = set(item[0] for item in list1) - set(object.id for object in list_in_my_bdd)
您可以改用列表推导式,只包含第一个元素在 list2
:
list1
的子列表
[item for item in list1 if item[0] in list2]
列表理解和集合怎么样?
list1 = [[1,'name1'], [2,'name2'], [3,'name3']]
good = {2,3}
print([[a,b] for a,b in list1 if a in good])
# [[2, 'name2'], [3, 'name3']]
你可以这样做。请注意,变量名称与您的问题相同,但 list2 实际上是一个集合(为了提高效率)。
list1 = [[1,'name1'], [2,'name2'], [3,'name3']]
list2 = {2, 3}
list3 = [item for item in list1 if item[0] in list2]
print(list3)
这看起来很像字典查找的工作,它可能比 O(N^2) 列表比较更快。因此,如果您想要 list1
的所有条目,其键包含在 list2
中,并且可以假设 list_of_items
中的键是唯一的,您可以这样做:
list1 = [[1,'name1'], [2,'name2'], [3,'name3']]
dict1 = dict(list1)
list2 = [2,3]
result = [dict1[k] for k in list2]
这要求列表 2 中包含的所有键实际上都在列表 1 中。否则result
None
个值
时间:
要在笔记本中重现计时:
import numpy as np
list1 = [[i, f"name{i}"] for i in range(10000)]
list2 = np.random.choice(range(10000), 1000).tolist()
dict1 = dict(list1)
%timeit [dict1.get(k) for k in list2]
%timeit [item for item in list1 if item[0] in list2]
>>>10000 loops, best of 5: 141 µs per loop
>>>10 loops, best of 5: 160 ms per loop
所以字典查找比列表理解快大约 1000 倍。
正如@Paul 提到的那样,如果可以直接使用字典替换 list1
的设置,这只会更快:
import numpy as np
list_of_items = [(j, f"name{i}") for j, i in enumerate(np.random.randint(0, 50000, 10000))]
list1 = list(filter(lambda x: "name" in x[1].lower(), list_of_items))
dict1 = dict(filter(lambda x: "name" in x[1].lower(), list_of_items))
To get list1 i'm doing this:
list(filter(lambda x: name in x[1].lower(), list_of_items))
你为什么不把支票也包括在这里:
list(filter(lambda x: name in x[1].lower() and x[0] in list2, list_of_items))