英文:
Efficient way to get an object from collection by value of one of its fields
问题
以下是翻译后的内容:
给定以下可能的输入之一,该函数执行以下操作:
- ID(数字字符串)
- 电子邮件(以@domain.tld结尾的字符串)
- 姓名(由字母和数字组成的任何其他字符串)
如果提供的内容不是 ID,则它尝试通过将给定属性与用户对象列表中每个用户的相应字段进行比较来检索用户 ID,所有这些用户对象都具有 ID 字段。
例如,如果提供了电子邮件,它应该从用户列表中找到具有提供的电子邮件的用户,然后返回此用户的 ID 字段的值。
在 Django 中,它会类似于这样:```User.objects.filter(email=input_string).first()```
在我的代码中,以下行执行此操作:
```user := next((user for user in users if user.email == input_string)```
它看起来不够优化且不够美观,但我很难找到更简洁的解决方案。
感谢任何关于此的建议。
```python
def validate_user_id(input_string, users):
if input_string.isdigit():
return {'type': 'user', 'id': input_string}
elif input_string.endswith(MAIL_DOMAIN):
if user := next((user for user in users if user.email == input_string), None):
return {'type': 'user', 'id': user.id}
return None
elif (input_string.isalnum() or
''.join(input_string.split('.')).isalnum()):
if user := next((user for user in users if user.nickname == input_string), None):
return {'type': 'user', 'id': user.id}
return None
raise ValueError(
MEMBER_FORMAT_INVALID.format(identifier=input_string))
英文:
The following function is given one of the following possible inputs:
- ID (numeric string)
- email (string ending with @domain.tld)
- name (any other alphanumeric string consisting)
If anything other than ID is given, it attempts to retrieve user ID by comparing a given attribute to the respective field of each user from a list of User objects, all of which have ID fields.
E.g., if an email is given, it should find a User from a list of Users that has the given email in its email field, then return value from this user's ID field.
In Django that would look like that User.objects.filter(email=input_string).first()
In my code, the following line is doing that:
user := next((user for user in users if user.email == input_string)
It looks suboptimal and ugly, but I'm struggling to find a neater solution.
Would appreciate any advice on that.
def validate_user_id(input_string, users):
if input_string.isdigit():
return {'type': 'user', 'id': input_string}
elif input_string.endswith(MAIL_DOMAIN):
if user := next((user for user in users if user.email == input_string), None):
return {'type': 'user', 'id': user.id}
return None
elif (input_string.isalnum() or
''.join(input_string.split('.')).isalnum()):
if user := next((user for user in users if user.nickname == input_string), None):
return {'type': 'user', 'id': user.id}
return None
raise ValueError(
MEMBER_FORMAT_INVALID.format(identifier=input_string))
答案1
得分: 1
为了使您的代码更加DRY和优化,可以使用以下方法:
- 检查输入字符串格式以识别用户的目标属性
- 不要从整个
user
对象中生成user.id
,而是使用生成器表达式
def validate_user_id(input_str, users):
if input_str.isdigit(): # 基本情况
return {'type': 'user', 'id': input_str}
if input_str.endswith(MAIL_DOMAIN):
attr = 'email'
elif (input_str.isalnum() or
''.join(input_str.split('.')).isalnum()):
attr = 'nickname'
else:
raise ValueError(MEMBER_FORMAT_INVALID.format(identifier=input_str))
user_id = next((user.id for user in users
if getattr(user, attr) == input_str), None)
if user_id:
return {'type': 'user', 'id': user_id}
return None
英文:
To make your code more DRY and optimized use the following approach:
- check the input string format to recognize the user's target attribute
- instead of whole
user
object yielduser.id
from generator expression
def validate_user_id(input_str, users):
if input_str.isdigit(): # base case
return {'type': 'user', 'id': input_str}
if input_str.endswith(MAIL_DOMAIN):
attr = 'email'
elif (input_str.isalnum() or
''.join(input_str.split('.')).isalnum()):
attr = 'nickname'
else:
raise ValueError(MEMBER_FORMAT_INVALID.format(identifier=input_str))
user_id = next((user.id for user in users
if getattr(user, attr) == input_str), None)
if user_id:
return {'type': 'user', 'id': user_id}
return None
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论