gpt4 book ai didi

Python3 - 处理大列表 : one class instance or creating new object for each element?

转载 作者:太空宇宙 更新时间:2023-11-04 04:40:37 25 4
gpt4 key购买 nike

这更像是一个一般的 Python 性能问题。

我创建了一个简单的类,目的是:

  1. 获取用户提供的电子邮件列表(在我的例子中,我使用 tkinter 的 GUI 进行输入)
  2. 使用 SHA256 算法对每封邮件进行哈希运算
  3. 返回散列值

代码:

import re
from collections import Iterable
from hashlib import sha256


class HashData():
"""Creates SHA256 sums for iterable prepared for AdWords Customer Match"""

def __init__(self, data):
if not isinstance(data, Iterable) or isinstance(data, str):
raise TypeError('data must be iterable and not a string, {} provided'.format(type(data)))

self.data = data

@staticmethod
def clean(value):
"""
Prepares string for AdWords' Customer Match requirements:
- no trailing spaces
- lowercase
:param value: str
:return: str
"""
if isinstance(value, str):
return value.strip().lower()
else:
return value

def validate_email(self):
"""Validate if self.data is properly formatted email and raise ValueError if not"""

pattern = re.compile(r"(^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$)")

for mail in self.data:
mail = HashData.clean(mail)

if not pattern.match(mail):
raise ValueError("'{}' doesn't seem to be a valid email!".format(mail))

def encrypt(self):
"""Creates generator for hashing self.data with SHA256 algorithm"""

for row in self.data:
value = HashData.clean(row)
value = value.encode('UTF8') # hashlib requires encoding before hashing

yield sha256(value).hexdigest()

来源:https://github.com/dutkiewicz/adwords-customer-match-hasher/blob/master/hasher/HashData.py

当用户提供大量输入(如 100 万行以上)时,我担心性能。因此我认为最好使用生成器 (self.encrypt()) 来降低内存使用量。但同时我用完整列表初始化对象,这可能是巨大的:/

我的问题是什么是更好的方法:

  1. 将输入加载到一个对象中并操作数据?
  2. 还是一次读取输入的一个元素,每次都创建HashData()实例?

如果我的问题太模糊,请在评论中告诉我。这是我面临的新问题,我可能无法以最好的方式表达自己。

最佳答案

看着你的例子,我对代码有了不同的看法。严格地证明我的观点会有问题,但直觉上 HashData 不是一个伟大的抽象。它处理类中的列表/生成器而不描述首先对列表元素进行操作。您的代码在内部重复 for 循环方法,这不是一个好兆头。

HashData 具有将您的方法汇集在一起​​的好处,但看看它从头开始,它基本上是一个 stings 列表上的一系列操作。没有对象的状态,有几个变量可以放在一起,或其他与函数相对的类操作系统常见的事情。

我对你的任务的看法是:

a) 你可以有如下几个“原始”函数,

import re
from hashlib import sha256

PATTERN = re.compile(r"(^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$)")

def is_string(raw_string: str) -> bool:
return isinstance(raw_string, str)

def clean(raw_string: str) -> str:
return raw_string.strip().lower()

def is_email(text: str, pattern=PATTERN) -> bool:
return pattern.match(text)

def encrypt(text: str):
text = text.encode('UTF8') # hashlib requires encoding before hashing
return sha256(text).hexdigest()

b) 您可以将这些小函数链接到一个操作管道中 如下所示或以其他方式

email_list = ['gigantic@list1000.com', 'tons@ofemail.org'] * 100

# check type
gen = filter(is_string, email_list)
# cleanup
gen = map(clean, gen)
# filter
gen = filter(is_email, gen)
# encrypt
hash_list = list(map(encrypt, gen))

c) 如果你真的想要一个类,我建议创建一些像下面这样的小而易于管理的东西

class Address:
def __init__(self, raw_string: str):
if not is_string(raw_string):
raise TypeError(raw_string)
text = clean(raw_string)
if not is_email(text):
raise ValueError(text)
self._text = text

def email(self):
return self._text

def hash(self):
return encrypt(self._text)

hash_list2 = [Address(s).hash() for s in email_list]

assert hash_list == hash_list2

关于Python3 - 处理大列表 : one class instance or creating new object for each element?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50717372/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com