在分配变量值之前使用的变量值仍然有效,这个 { k: v for k, v in ... } 语法是如何工作的?
Variable values used before they are assigned and still it works, how does this { k: v for k, v in ... } syntax work?
在下面的代码中,我无法理解变量 field
和 value
的使用方式,因为它们是在 for
循环的下一行中分配的。
我查看了此语法和示例中的 for
,但找不到任何有用的信息来解释此行为。
match = re.search(someregx, some_text)
current_row = {
field: value.strip() if value else '' for field, value in match.groupdict().items()
}
是字典理解,相当于
current_row = {}
for field, value in match.groupdict().items():
if value:
current_row[field] = value.strip()
else:
current_row[field] = ''
这是一个dict comprehension。它根据指定的表达式创建字典。 {...}
等同于 Python 中的 dict(...)
语法。 (在这种特殊情况下,它专门从 iterable
创建一个 dict(iterable)
;见底部)。
好的,那么这些 Python 行话是什么意思?首先,考虑 Python 中的 list comprehension 这是一个从给定输入创建 list 的表达式,例如:
odd_numbers = [ n for n in range(100) if n%2 == 1 ]
同理,我们先从最基本的dict理解开始:
{ k: v for k, v in ... }
并注意 RHS match.groupdict().items()
是一个可迭代的,我们只是迭代正则表达式匹配的输出,作为字典项。 (让我们在 RHS 后面写 ...
,以尽量减少混乱)。
接下来,在Python中添加v if v else ''
是一个conditional expression,这里只是处理其中一个value
是None的情况,并给出 empty-string '' 而不是 None (如果你试图对它做进一步的 string-processing 会(恼人地)抛出异常,并且大概我们不想写 try...except
大约每次我们尝试处理字符串时 value
)。正如您所说,它会在 Python 中抛出新用户,因为条件表达式中的 if
在定义它们的可迭代对象之前。第一次看到它时,它看起来像是一堆顺序错误的关键字:)
(推导式、条件表达式以及组合和嵌套这些的组合允许 Python 在紧凑的同时真正表达。)
因此我们正在寻找:
{ k: v if v else '' for k, v in ... }
或者在这种特殊情况下,调用关键变量 field
:
{ field: value.strip() if value else '' for field, value in match.groupdict().items() }
一旦您知道 {...}
等同于 dict(...)
,help(dict)
信息将帮助您理解 此代码正在创建一个 dict(iterable)
iterable
; dict(...)
:
语法中显示的第三种情况
class dict(object)
| dict() -> new empty dictionary
|
| dict(mapping) -> new dictionary initialized from a mapping object's
| (key, value) pairs
|
| dict(iterable) -> new dictionary initialized as if via:
| d = {}
| for k, v in iterable:
| d[k] = v
| ...
杂项提示:
- 格式化:不要像 C/C++/Java 复合语句块一样在单独的行上格式化大括号,Python 根本不使用那样的大括号,我们为此感到非常自豪 :)。在 Python 中
{...}
等同于 dict(...)
。因此,每当您看到大括号时,您就是在查看字典、嵌套字典、dict-of-list、JSON 表达式等...
- ... 或者
set
。 set
本质上是一个有键但没有值的字典,例如{'b', 'f', 'g'}
。你也可以有一个 set comprehension,除了 { k: v for k, v ... }
它只是 { k for k in ... }
。这是一个示例:odd_numbers = { n for n in range(100) if n%2 == 1 }
。在集合中,顺序无关紧要,这与元组不同。
- 没有周围的 spaces:我在
[ ... ]
或 { ... }
周围用 space 写了 dict,list 和 set comprehensions,但这只是为了清楚解释语法。 Pythonic (PEP-8) 方式不是写一个 space.
- 简洁:在字典理解中通常会给出
key
、value
非常短或 one-letter 名称 { k: v for k, v in ... }
,尤其是。如果它们是复杂的表达式,那么您就不会反复浪费 space 并且需要大行或换行。
- 相关问题:Create a dictionary with list comprehension, How to use if/else in a dictionary comprehension?
- 也请略读 Python Programming FAQ and Functional Programming HOWTO,刚好足以让您理解概念,并在将来看到有人使用它时识别语法,然后您可以返回并阅读更多详细信息。
在下面的代码中,我无法理解变量 field
和 value
的使用方式,因为它们是在 for
循环的下一行中分配的。
我查看了此语法和示例中的 for
,但找不到任何有用的信息来解释此行为。
match = re.search(someregx, some_text)
current_row = {
field: value.strip() if value else '' for field, value in match.groupdict().items()
}
是字典理解,相当于
current_row = {}
for field, value in match.groupdict().items():
if value:
current_row[field] = value.strip()
else:
current_row[field] = ''
这是一个dict comprehension。它根据指定的表达式创建字典。 {...}
等同于 Python 中的 dict(...)
语法。 (在这种特殊情况下,它专门从 iterable
创建一个 dict(iterable)
;见底部)。
好的,那么这些 Python 行话是什么意思?首先,考虑 Python 中的 list comprehension 这是一个从给定输入创建 list 的表达式,例如:
odd_numbers = [ n for n in range(100) if n%2 == 1 ]
同理,我们先从最基本的dict理解开始:
{ k: v for k, v in ... }
并注意 RHS match.groupdict().items()
是一个可迭代的,我们只是迭代正则表达式匹配的输出,作为字典项。 (让我们在 RHS 后面写 ...
,以尽量减少混乱)。
接下来,在Python中添加v if v else ''
是一个conditional expression,这里只是处理其中一个value
是None的情况,并给出 empty-string '' 而不是 None (如果你试图对它做进一步的 string-processing 会(恼人地)抛出异常,并且大概我们不想写 try...except
大约每次我们尝试处理字符串时 value
)。正如您所说,它会在 Python 中抛出新用户,因为条件表达式中的 if
在定义它们的可迭代对象之前。第一次看到它时,它看起来像是一堆顺序错误的关键字:)
(推导式、条件表达式以及组合和嵌套这些的组合允许 Python 在紧凑的同时真正表达。)
因此我们正在寻找:
{ k: v if v else '' for k, v in ... }
或者在这种特殊情况下,调用关键变量 field
:
{ field: value.strip() if value else '' for field, value in match.groupdict().items() }
一旦您知道 {...}
等同于 dict(...)
,help(dict)
信息将帮助您理解 此代码正在创建一个 dict(iterable)
iterable
; dict(...)
:
class dict(object)
| dict() -> new empty dictionary
|
| dict(mapping) -> new dictionary initialized from a mapping object's
| (key, value) pairs
|
| dict(iterable) -> new dictionary initialized as if via:
| d = {}
| for k, v in iterable:
| d[k] = v
| ...
杂项提示:
- 格式化:不要像 C/C++/Java 复合语句块一样在单独的行上格式化大括号,Python 根本不使用那样的大括号,我们为此感到非常自豪 :)。在 Python 中
{...}
等同于dict(...)
。因此,每当您看到大括号时,您就是在查看字典、嵌套字典、dict-of-list、JSON 表达式等... - ... 或者
set
。set
本质上是一个有键但没有值的字典,例如{'b', 'f', 'g'}
。你也可以有一个 set comprehension,除了{ k: v for k, v ... }
它只是{ k for k in ... }
。这是一个示例:odd_numbers = { n for n in range(100) if n%2 == 1 }
。在集合中,顺序无关紧要,这与元组不同。 - 没有周围的 spaces:我在
[ ... ]
或{ ... }
周围用 space 写了 dict,list 和 set comprehensions,但这只是为了清楚解释语法。 Pythonic (PEP-8) 方式不是写一个 space. - 简洁:在字典理解中通常会给出
key
、value
非常短或 one-letter 名称{ k: v for k, v in ... }
,尤其是。如果它们是复杂的表达式,那么您就不会反复浪费 space 并且需要大行或换行。 - 相关问题:Create a dictionary with list comprehension, How to use if/else in a dictionary comprehension?
- 也请略读 Python Programming FAQ and Functional Programming HOWTO,刚好足以让您理解概念,并在将来看到有人使用它时识别语法,然后您可以返回并阅读更多详细信息。