为什么当我将新元素附加到 TUPLE 时它会起作用?
Why does it work when I append a new element to a TUPLE?
既然元组在 Python 中是不可变的数据类型并且元组推导式不是问题那么为什么使用圆括号而不是方括号的列表推导式可以正常工作并生成常规元组?
我认为圆括号用于定义元组而不是列表(我知道我没有错)。
根据我的理解,我将值附加到已经定义的元组并且我能够更新元组并且这不应该发生(在 Python 中),因为元组是不可变的.
我没有收到任何错误,请有人告诉我对此有合理的解释。
这是我的代码:
ignore = (r"^\@define\s")
x = tuple()
(x.append(True if re.search(regex, line) else False) for regex in ignore)
if True in x:
print("How is this possible?")
让我们展示一个更简单的示例,其形式可以让您在家中在 REPL 中进行操作:
>>> def error(): raise Exception
...
>>> (error() for x in range(5))
<generator object <genexpr> at 0x7fb1a371f2d0>
(error() for x in range(5)
是一个 genexp——一个生成器表达式。当它被评估时,它会生成一个生成器对象,该对象可以根据需要懒惰地生成项目——但现在,我们还没有要求它生成任何东西!因此,其中包含的代码 none 具有 运行.
相比之下,让我们看看当我们尝试将生成器的输出扩展为元组时会发生什么:
>>> tuple(_)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 1, in <genexpr>
File "<stdin>", line 1, in error
Exception
轰!
未抛出错误,因为您使用的是 生成器表达式。
>>> x = tuple()
>>> x
()
>>> (x.append(i) for i in range(10))
<generator object <genexpr> at 0x110bede60>
生成器是惰性求值的,由于您甚至没有在变量中捕获生成器,它只是被垃圾收集。但是,看看当我 使用生成器时会发生什么:
>>> g = (x.append(i) for i in range(10))
>>> next(g)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 1, in <genexpr>
AttributeError: 'tuple' object has no attribute 'append'
A generator 是一种快速、酷的编写迭代器的方法。 generator 表达式本质上是 "list comprehension for generators",但您可以使用 yield
:
编写生成器
>>> def my_generator():
... yield 1
... yield 3
...
>>> g = my_generator()
>>> next(g)
1
>>> next(g)
3
>>> next(g)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
>>> list(my_generator())
[1, 3]
>>>
现在,生成器表达式的妙处在于您可以将它们与 tuple
构造函数结合起来,它接受任何可迭代对象,并且您可以理解 poor-man 的元组! *注意,如果只有一个参数,您可以将括号放在函数参数中:
>>> tuple(x for x in range(20))
(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19)
>>>
顺便说一句,你应该永远不要 运行这样的代码:
>>> x = []
>>> [x.append(i) for i in range(10)]
[None, None, None, None, None, None, None, None, None, None]
>>> x
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
首先,它很浪费,因为它创建了一个完全无用的 None
列表。其次,它混合了功能构造、列表理解和状态更改 (.append
),这是一种糟糕的形式。 Python 程序员希望列表理解不会那样做。 命令式代码只需使用 for-loop。
既然元组在 Python 中是不可变的数据类型并且元组推导式不是问题那么为什么使用圆括号而不是方括号的列表推导式可以正常工作并生成常规元组?
我认为圆括号用于定义元组而不是列表(我知道我没有错)。
根据我的理解,我将值附加到已经定义的元组并且我能够更新元组并且这不应该发生(在 Python 中),因为元组是不可变的.
我没有收到任何错误,请有人告诉我对此有合理的解释。
这是我的代码:
ignore = (r"^\@define\s")
x = tuple()
(x.append(True if re.search(regex, line) else False) for regex in ignore)
if True in x:
print("How is this possible?")
让我们展示一个更简单的示例,其形式可以让您在家中在 REPL 中进行操作:
>>> def error(): raise Exception
...
>>> (error() for x in range(5))
<generator object <genexpr> at 0x7fb1a371f2d0>
(error() for x in range(5)
是一个 genexp——一个生成器表达式。当它被评估时,它会生成一个生成器对象,该对象可以根据需要懒惰地生成项目——但现在,我们还没有要求它生成任何东西!因此,其中包含的代码 none 具有 运行.
相比之下,让我们看看当我们尝试将生成器的输出扩展为元组时会发生什么:
>>> tuple(_)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 1, in <genexpr>
File "<stdin>", line 1, in error
Exception
轰!
未抛出错误,因为您使用的是 生成器表达式。
>>> x = tuple()
>>> x
()
>>> (x.append(i) for i in range(10))
<generator object <genexpr> at 0x110bede60>
生成器是惰性求值的,由于您甚至没有在变量中捕获生成器,它只是被垃圾收集。但是,看看当我 使用生成器时会发生什么:
>>> g = (x.append(i) for i in range(10))
>>> next(g)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 1, in <genexpr>
AttributeError: 'tuple' object has no attribute 'append'
A generator 是一种快速、酷的编写迭代器的方法。 generator 表达式本质上是 "list comprehension for generators",但您可以使用 yield
:
>>> def my_generator():
... yield 1
... yield 3
...
>>> g = my_generator()
>>> next(g)
1
>>> next(g)
3
>>> next(g)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
>>> list(my_generator())
[1, 3]
>>>
现在,生成器表达式的妙处在于您可以将它们与 tuple
构造函数结合起来,它接受任何可迭代对象,并且您可以理解 poor-man 的元组! *注意,如果只有一个参数,您可以将括号放在函数参数中:
>>> tuple(x for x in range(20))
(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19)
>>>
顺便说一句,你应该永远不要 运行这样的代码:
>>> x = []
>>> [x.append(i) for i in range(10)]
[None, None, None, None, None, None, None, None, None, None]
>>> x
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
首先,它很浪费,因为它创建了一个完全无用的 None
列表。其次,它混合了功能构造、列表理解和状态更改 (.append
),这是一种糟糕的形式。 Python 程序员希望列表理解不会那样做。 命令式代码只需使用 for-loop。