Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 计算列表1中的项目在列表2中出现的次数_Python_Python 3.x - Fatal编程技术网

Python 计算列表1中的项目在列表2中出现的次数

Python 计算列表1中的项目在列表2中出现的次数,python,python-3.x,Python,Python 3.x,我有两份清单: 1. ['a', 'b', 'c'] 2. ['a', 'd', 'a', 'b'] 我希望字典输出如下: {'a': 2, 'b': 1, 'c': 0} 我已经做到了: #b = list #1 #words = list #2 c = {} for i in b: c.update({i:words.count(i)}) 但它非常慢,我需要处理像10MB的txt文件 编辑:完整代码,当前正在测试未使用的导入 import string import os i

我有两份清单:

1. ['a', 'b', 'c']
2. ['a', 'd', 'a', 'b']
我希望字典输出如下:

{'a': 2, 'b': 1, 'c': 0}
我已经做到了:

#b = list #1
#words = list #2

c = {}
for i in b:
    c.update({i:words.count(i)})
但它非常慢,我需要处理像10MB的txt文件

编辑:完整代码,当前正在测试未使用的导入

import string
import os
import operator
import time
from collections import Counter
def getbookwords():

    a = open("wu.txt", encoding="utf-8")

    b = a.read().replace("\n", "").lower()
    a.close()

    b.translate(string.punctuation)

    b = b.split(" ")
    return b

def wordlist(words):

    a = open("wordlist.txt")
    b = a.read().lower()
    b = b.split("\n")

    a.close()

    t = time.time()
    #c = dict((i, words.count(i)) for i in b )

    c  = Counter(words)
    result = {k: v for k, v in c.items() if k in set(b)}
    print(time.time() - t)

    sorted_d = sorted(c.items(), key=operator.itemgetter(1))    
    return(sorted_d)

print(wordlist(getbookwords()))
尝试使用并将
b
移动到
集合
,而不是
列表

from collections import Counter

c = Counter(words)
b = set(b)
result = {k: v for k, v in c.items() if k in b}
另外,如果你可以懒洋洋地读单词,而不是创建一个应该更快的中间列表


计数器
提供您想要的功能(计算项目),并且根据
集合过滤结果
使用哈希,这应该快得多。

由于速度目前是一个问题,因此可能值得考虑不通过列表来计算您想要计算的每件事情。
set()
函数允许您仅使用列表中的
单词
中的唯一

在任何情况下,速度都要记住的一点是行
unique\u words=set(b)
。如果没有这一点,将对列表进行一次完整的遍历,以便在每次迭代中从
b
创建一个集合,无论您使用哪种类型的数据结构

c = {k:0 for k in set(words)}
for w in words:
    c[w] += 1
unique_words = set(b)
c = {k:counts[k] for k in c if k in unique_words}
或者,
defaultdicts
可以用来消除一些初始化

from collections import defaultdict

c = defaultdict(int)
for w in words:
    c[w] += 1
unique_words = set(b)
c = {k:counts[k] for k in c if k in unique_words}
为了完整性起见,我确实喜欢其他答案中基于
计数器的解决方案(如Reut Sharabani)。代码更干净,尽管我还没有对其进行基准测试,但如果内置计数类比使用字典的自制解决方案更快,我也不会感到惊讶

from collections import Counter

c = Counter(words)
unique_words = set(b)
c = {k:v for k, v in c.items() if k in unique_words}

您可以在生成器上使用
collection.Counter
,该生成器使用
set
查找跳过被忽略的键

from collections import Counter

keys = ['a', 'b', 'c']
lst = ['a', 'd', 'a', 'b']

unique_keys = set(keys)
count = Counter(x for x in lst if x in unique_keys)

print(count) # Counter({'a': 2, 'b': 1})

# count['c'] == 0

请注意,
count['c']
未打印,但在
计数器中默认情况下仍为
0

以下是我刚刚在repl中给出的一个示例。假设列表2中没有重复项。我们使用字典创建一个哈希表。对于列表中匹配两个的每个项,我们创建一个键值对,该项为键,并将值设置为0

接下来我们遍历第二个列表,对于每个值,我们检查值是否已经定义,如果已经定义,则使用键增加值。否则,我们忽略

尽可能少的迭代次数。每个列表中的每个项目只命中一次

x=[1,2,3,4,5];
z=[1,2,2,2,1];
y={};
对于x中的n:
y[n]=0//将列表中每个项目的值设置为零
对于z中的n:
if(y中的n)://如果我们已经在散列中定义了值,则递增1
y[n]+=1;
打印(y)

@makone,以上答案是可以理解的。您还可以尝试下面的代码示例,该示例使用Python的
collections
模块中的
计数器()

你可以试试看

Python代码» 输出»
你能告诉我你是怎么读这个文件的吗?如果不需要的话,不要把它读到一个列表中。“慢”有多慢?它需要60多秒。。。目前正在测试第一个答案,时间太长@MakaloneLOgman不,这是不一样的,它稍微更有效,因为它使用生成器理解来跳过不在列表中的单词的计数keys@MakaloneLOgman那是因为我忘了在循环外创建集合。此解决方案将非常快速。列表1中键的
位可以使用类似于
set(list1)
的散列结构加快,就像在其他答案中一样。这可能对OP的原始数据很有效,但恶意反例会使其性能异常糟糕。@Musgrave,感谢您的建议和编辑。我认为list1将被视为唯一的一组键。使用set()很好,因为用户还可以使用可能导致性能问题的重复元素。谢谢!令人惊讶的是,我有时会忘记简单的问题解决方案。
from collections import Counter

list1 = ['a', 'b', 'c']
list2 = ['a', 'd', 'a', 'b']
counter = Counter(list2)

d = {key: counter[key] for key in set(list1)}
print(d)
{'a': 2, 'c': 0, 'b': 1}