使用另一个列表计算一个元素的出现次数时有什么更快的方法
What faster way is there when counting occurrences of elements in one using another list
如果我有两个列表,List_A
和 List_B
如果我想从 [=11= 计算 List_B
中每个元素出现的次数,有什么更快的方法] 并在新的 List_C
中解析结果?
通常我使用列表理解,但是一旦 List_A
或 List_B
中的元素数量增加到 100 000 以上,它就会开始花费大量时间。
List_A = ['a', 'd','f','h','g','e','f','a','f','h','h','d','b','c','c','a']
List_B = ['a', 'b','c','d','e','f','g','h']
List_C = [List_A.count(x) for x in List_B]
List_C
#Output:
#List_C = [3, 1, 2, 2, 1, 3, 1, 3]
使用您的解决方案,您执行的计算数量等于 len(List_A) * len(List_B)
(您的列表理解)。
相反,首先计算出现的次数,然后进行列表理解:
List_A = ['a', 'd','f','h','g','e','f','a','f','h','h','d','b','c','c','a']
List_B = ['a', 'b','c','d','e','f','g','h']
occ = dict()
for x in List_A:
occ.setdefault(x, 0)
occ[x] += 1
List_C = [occ.get(x, 0) for x in List_B]
通过这种方式你遍历了List_A
一次和List_B
一次。
[编辑]
更新了最后一行的列表理解以解决 x
不在 List_A
中的情况(参见@AchilleG 的评论)
def a():
List_A = ['a', 'd','f','h','g','e','f','a','f','h','h','d','b','c','c','a']
List_B = ['a', 'b','c','d','e','f','g','h', 'z']
count = Counter(List_A)
List_C = [count.get(x) for x in List_B]
100000 次循环,5 次循环中的最佳次数:每次循环 2.96 微秒
使用 Counter() 并检查 None:
def b():
List_A = ['a', 'd','f','h','g','e','f','a','f','h','h','d','b','c','c','a']
List_B = ['a', 'b','c','d','e','f','g','h', 'z']
count = Counter(List_A)
List_C = []
for x in List_B:
val = count.get(x)
if val != None:
List_C.append(val)
100000 次循环,5 次循环中的最佳次数:每次循环 3.45 微秒
不检查 None 值:
def c():
List_A = ['a', 'd','f','h','g','e','f','a','f','h','h','d','b','c','c','a']
List_B = ['a', 'b','c','d','e','f','g','h', 'z']
count = Counter(List_A)
List_C = []
for x in List_B:
List_C.append(count.get(x))
100000 次循环,5 次循环中的最佳次数:每次循环 3.04 微秒
使用@Mafa 的解决方案,如果 List_B 具有未出现在 List_A 中的值,则该解决方案不起作用:
def d():
List_A = ['a', 'd','f','h','g','e','f','a','f','h','h','d','b','c','c','a']
List_B = ['a', 'b','c','d','e','f','g','h']
occ = dict()
for x in List_A:
occ.setdefault(x, 0)
occ[x] += 1
List_C = [occ[x] for x in List_B]
100000 次循环,5 次循环中的最佳次数:每次 2.59 微秒
Mafa 检查现有值的解决方案:
def e():
List_A = ['a', 'd','f','h','g','e','f','a','f','h','h','d','b','c','c','a']
List_B = ['a', 'b','c','d','e','f','g','h']
occ = dict()
for x in List_A:
occ.setdefault(x, 0)
occ[x] += 1
List_C = [occ.get(x, 0) for x in List_B]
100000 次循环,5 次循环中的最佳次数:每次循环 3.1 微秒
接下来的两个功能由@Alex Waygood 提出
def f():
List_A = ['a', 'd','f','h','g','e','f','a','f','h','h','d','b','c','c','a']
List_B = ['a', 'b','c','d','e','f','g','h']
c = Counter(filter(set(List_B).__contains__, List_A))
List_C = [v for k, v in sorted(c.items())]
50000 次循环,5 次循环中的最佳次数:每次循环 4.45 微秒
def g():
List_A = ['a', 'd','f','h','g','e','f','a','f','h','h','d','b','c','c','a']
List_B = ['a', 'b','c','d','e','f','g','h', 'z']
c = Counter(filter(List_B.__contains__, List_A))
List_C = [v for k, v in sorted(c.items())]
50000 次循环,5 次循环中的最佳次数:每次循环 4.78 微秒
(不确定这里是否需要除以二——显然不需要——,因为有 50000 个循环而不是 100000 个循环,如果是这样的话我们在这里有明显的赢家)
如果我有两个列表,List_A
和 List_B
如果我想从 [=11= 计算 List_B
中每个元素出现的次数,有什么更快的方法] 并在新的 List_C
中解析结果?
通常我使用列表理解,但是一旦 List_A
或 List_B
中的元素数量增加到 100 000 以上,它就会开始花费大量时间。
List_A = ['a', 'd','f','h','g','e','f','a','f','h','h','d','b','c','c','a']
List_B = ['a', 'b','c','d','e','f','g','h']
List_C = [List_A.count(x) for x in List_B]
List_C
#Output:
#List_C = [3, 1, 2, 2, 1, 3, 1, 3]
使用您的解决方案,您执行的计算数量等于 len(List_A) * len(List_B)
(您的列表理解)。
相反,首先计算出现的次数,然后进行列表理解:
List_A = ['a', 'd','f','h','g','e','f','a','f','h','h','d','b','c','c','a']
List_B = ['a', 'b','c','d','e','f','g','h']
occ = dict()
for x in List_A:
occ.setdefault(x, 0)
occ[x] += 1
List_C = [occ.get(x, 0) for x in List_B]
通过这种方式你遍历了List_A
一次和List_B
一次。
[编辑]
更新了最后一行的列表理解以解决 x
不在 List_A
中的情况(参见@AchilleG 的评论)
def a():
List_A = ['a', 'd','f','h','g','e','f','a','f','h','h','d','b','c','c','a']
List_B = ['a', 'b','c','d','e','f','g','h', 'z']
count = Counter(List_A)
List_C = [count.get(x) for x in List_B]
100000 次循环,5 次循环中的最佳次数:每次循环 2.96 微秒
使用 Counter() 并检查 None:
def b():
List_A = ['a', 'd','f','h','g','e','f','a','f','h','h','d','b','c','c','a']
List_B = ['a', 'b','c','d','e','f','g','h', 'z']
count = Counter(List_A)
List_C = []
for x in List_B:
val = count.get(x)
if val != None:
List_C.append(val)
100000 次循环,5 次循环中的最佳次数:每次循环 3.45 微秒
不检查 None 值:
def c():
List_A = ['a', 'd','f','h','g','e','f','a','f','h','h','d','b','c','c','a']
List_B = ['a', 'b','c','d','e','f','g','h', 'z']
count = Counter(List_A)
List_C = []
for x in List_B:
List_C.append(count.get(x))
100000 次循环,5 次循环中的最佳次数:每次循环 3.04 微秒
使用@Mafa 的解决方案,如果 List_B 具有未出现在 List_A 中的值,则该解决方案不起作用:
def d():
List_A = ['a', 'd','f','h','g','e','f','a','f','h','h','d','b','c','c','a']
List_B = ['a', 'b','c','d','e','f','g','h']
occ = dict()
for x in List_A:
occ.setdefault(x, 0)
occ[x] += 1
List_C = [occ[x] for x in List_B]
100000 次循环,5 次循环中的最佳次数:每次 2.59 微秒
Mafa 检查现有值的解决方案:
def e():
List_A = ['a', 'd','f','h','g','e','f','a','f','h','h','d','b','c','c','a']
List_B = ['a', 'b','c','d','e','f','g','h']
occ = dict()
for x in List_A:
occ.setdefault(x, 0)
occ[x] += 1
List_C = [occ.get(x, 0) for x in List_B]
100000 次循环,5 次循环中的最佳次数:每次循环 3.1 微秒
接下来的两个功能由@Alex Waygood 提出
def f():
List_A = ['a', 'd','f','h','g','e','f','a','f','h','h','d','b','c','c','a']
List_B = ['a', 'b','c','d','e','f','g','h']
c = Counter(filter(set(List_B).__contains__, List_A))
List_C = [v for k, v in sorted(c.items())]
50000 次循环,5 次循环中的最佳次数:每次循环 4.45 微秒
def g():
List_A = ['a', 'd','f','h','g','e','f','a','f','h','h','d','b','c','c','a']
List_B = ['a', 'b','c','d','e','f','g','h', 'z']
c = Counter(filter(List_B.__contains__, List_A))
List_C = [v for k, v in sorted(c.items())]
50000 次循环,5 次循环中的最佳次数:每次循环 4.78 微秒
(不确定这里是否需要除以二——显然不需要——,因为有 50000 个循环而不是 100000 个循环,如果是这样的话我们在这里有明显的赢家)