你能解释一下这里发生了什么吗(gmaildottrick生成器)



我真的不懂

def dot_trick(handle):
f = lambda s:s[11:] and [s[0]+w+x for x in f(s[1:]) for w in('.','')] or [s]
return f(handle)

在互联网上找到它,它生成所有"邮件点技巧">电子邮件变体

这看起来像是魔术,如此紧凑,有人能一步一步地解释一下这里发生了什么吗?或者在没有lambda函数的情况下重新表述

它主要使用列表理解和用二进制运算符实现的三进制运算符

它使用的模式已被弃用,因为在Python 2.5发布时,PEP308中已经引入了三元运算符的内置语法。

此外

s[11:] and [s[0]+w+x for x in f(s[1:]) for w in('.','')] or [s]

可以分为:

def f(s)
if len(s[11:]) > 0:
lst = []
for w in (".",''):
for x in f(s[1:]): #s[:1] removes first character
lst.append(s[0] + w + x)
return lst
return [s]

以下是它在libcst库中显示的内容:

>>> print(libcst.tools.dump(cst.parse_expression("s[11:] and [s[0]+w+x for x in f(s[1:]) for w in('.','')] or [s]")))
BooleanOperation(
left=BooleanOperation(
left=Subscript(
value=Name(
value='s',
),
slice=[
SubscriptElement(
slice=Slice(
lower=Integer(
value='11',
),
upper=None,
),
),
],
),
operator=And(),
right=ListComp(
elt=BinaryOperation(
left=BinaryOperation(
left=Subscript(
value=Name(
value='s',
),
slice=[
SubscriptElement(
slice=Index(
value=Integer(
value='0',
),
),
),
],
),
operator=Add(),
right=Name(
value='w',
),
),
operator=Add(),
right=Name(
value='x',
),
),
for_in=CompFor(
target=Name(
value='x',
),
iter=Call(
func=Name(
value='f',
),
args=[
Arg(
value=Subscript(
value=Name(
value='s',
),
slice=[
SubscriptElement(
slice=Slice(
lower=Integer(
value='1',
),
upper=None,
),
),
],
),
),
],
),
inner_for_in=CompFor(
target=Name(
value='w',
),
iter=Tuple(
elements=[
Element(
value=SimpleString(
value="'.'",
),
),
Element(
value=SimpleString(
value="''",
),
),
],
),
),
),
),
),
operator=Or(),
right=List(
elements=[
Element(
value=Name(
value='s',
),
),
],
),
)

以下是它为上一个内置库打印的内容:

>>> print(ast.dump(ast.parse("s[11:] and [s[0]+w+x for x in f(s[1:]) for w in('.','')] or [s]")))
Module(body=[Expr(value=BoolOp(op=Or(), values=[BoolOp(op=And(), values=[Subscript(value=Name(id='s', ctx=Load()), slice=Slice(lower=Constant(value=11)), ctx=Load()), ListComp(elt=BinOp(left=BinOp(left=Subscript(value=Name(id='s', ctx=Load()), slice=Constant(value=0), ctx=Load()), op=Add(), right=Name(id='w', ctx=Load())), op=Add(), right=Name(id='x', ctx=Load())), generators=[comprehension(target=Name(id='x', ctx=Store()), iter=Call(func=Name(id='f', ctx=Load()), args=[Subscript(value=Name(id='s', ctx=Load()), slice=Slice(lower=Constant(value=1)), ctx=Load())], keywords=[]), ifs=[], is_async=0), comprehension(target=Name(id='w', ctx=Store()), iter=Tuple(elts=[Constant(value='.'), Constant(value='')], ctx=Load()), ifs=[], is_async=0)])]), List(elts=[Name(id='s', ctx=Load())], ctx=Load())]))], type_ignores=[])

这就是它在可读形式中的样子:

def gen_dot_trick(handle):
if len(handle) <= 11: 
# stop recursion at the last character of the user name
# 11 is the length of "X@gmail.com"
yield handle
else:
first, rest = handle[0], handle[1:]
for sub in gen_dot_trick(rest):
# with and without the dot after the first char
yield first + '.' + sub
yield first       + sub
def dot_trick(handle):
return list(gen_dot_trick(handle))

最新更新