1、生成器解析超大json, 节省内存,不会都读出来,next依次读取
15.python的for循环与迭代器、生成器 - scolia - 博客园
import ijson with open('test.json', 'r', encoding='utf-8') as f: objects = ijson.items(f, 'earth.europe.item') #这个objects在这里就是相当于一个生成器,可以调用next函数取它的下一个值 while True: try: print(objects.__next__()) except StopIteration as e: print("数据读取完成") break
很好,接下来看一下效果如何。
{'name': 'Paris', 'type': 'city', 'info': 'aaa'} {'name': 'Thames', 'type': 'river', 'info': 'sss'} {'name': 'yyy', 'type': 'city', 'info': 'aaa'} {'name': 'eee', 'type': 'river', 'info': 'sss'}
2、场景需求
一个保存了400W条分词后的中文文本数据的文件,每条数据大概200-400个词,电脑内存32G,现在需要统计词频,用做后续算法的处理。
这个问题该怎么处理呢?我理解到的方法,就是很简单直接用生成器,然后喂给Collection.Counter()就可以统计出词频了,也恰好Collection.Counter()支持生成器输入。
上代码:
def get_sentence_words(path):
files = os.listdir(path)
for file in files:
file_path = os.path.join(path, file)
with open(file_path, 'r') as f:
for line in tqdm(f, desc='read sentence_cuts'):
line = line.strip().split(' ')
for word in line:
yield word
if __name__ == '__main__':
words_gen = get_sentence_words('data_set/sentence_cut')
weight_dict = Counter(words_gen)
print('len(weight_dict)',len(weight_dict))
total = 0
for v in weight_dict.values():
total += v
print('total words is %d'% total)
处理大量数据
生成器一次返回一个结果,而不是一次返回所有结果。这对于大量数据的计算非常有用。
不用生成器,本地尝试电脑死机():
sum([i for i in range(10000000000000)])
使用用生成器,本地尝试,计算时间比较长,但是没有导致系统死机:
sum(i for i in range(10000000000000))
4、
所有的函数都是可调用对象。一个类实例也可以变成一个可调用对象,只需要实现一个特殊方法__call__ ,我们把 Person 类变成一个可调用对象:
class Person():
def __init__(self, name, gender):
self.name = name
self.gender = gender
def __call__(self, friend):
print('My name is %s...' % self.name)
print('My friend is %s...' % friend)
现在可以对 Person 实例直接调用:
B = Person('Jack','male')
B('Mark')