当前位置: 首页 > 面试题库 >

同时声明多个变量的更优雅的方式

潘嘉佑
2023-03-14
问题内容

要在“相同时间”声明多个变量,我会这样做:

a, b = True, False

但是,如果我不得不声明更多的变量,它将变得越来越优雅:

a, b, c, d, e, f, g, h, i, j = True, True, True, True, True, False, True ,True , True, True

有没有更好/优雅/方便的方法来做到这一点?

这必须是非常基本的,但是如果我确实使用列表或元组来存储变量,那么我将不得不如何处理,这样我将有所帮助:

aList = [a,b]

无效,我必须这样做:

a, b = True, True

还是我想念什么?


问题答案:

正如其他人所建议的那样,不太可能将10个不同的局部变量与布尔值一起使用是编写例程的最佳方法(尤其是如果它们确实具有一个字母的名称时:)

根据您正在执行的操作,可以改用词典。例如,如果要为一组单字母标志设置布尔值预设值,则可以执行以下操作:

>>> flags = dict.fromkeys(["a", "b", "c"], True)
>>> flags.update(dict.fromkeys(["d", "e"], False))
>>> print flags
{'a': True, 'c': True, 'b': True, 'e': False, 'd': False}

如果您愿意,也可以使用一个赋值语句来做到这一点:

>>> flags = dict(dict.fromkeys(["a", "b", "c"], True),
...              **dict.fromkeys(["d", "e"], False))
>>> print flags
{'a': True, 'c': True, 'b': True, 'e': False, 'd': False}

的第二个参数dict并非完全为此目的而设计的:它的真正含义是允许您使用关键字参数(如)来覆盖字典中的各个元素d=False。上面的代码将表达式的结果**分解为一组关键字参数,这些参数传递给调用的函数。这当然是创建字典的可靠方法,而且人们似乎至少接受了这种习语,但我怀疑有人可能认为它是非Python的。
</disclaimer>

另一种方法,这是最直观的,如果你会经常使用这种模式,是定义你的数据作为标志值(列表TrueFalse映射到标志名(单字符串))。然后,您可以将此数据定义转换为反向字典,该字典将标志名称映射到标志值。使用嵌套列表理解可以很简洁地完成此操作,但是这是一个非常易读的实现:

>>> def invert_dict(inverted_dict):
...     elements = inverted_dict.iteritems()
...     for flag_value, flag_names in elements:
...         for flag_name in flag_names:
...             yield flag_name, flag_value
... 
>>> flags = {True: ["a", "b", "c"], False: ["d", "e"]}
>>> flags = dict(invert_dict(flags))
>>> print flags
{'a': True, 'c': True, 'b': True, 'e': False, 'd': False}

该函数invert_dict是一个生成器函数。它
生成产生 -意味着它 反复返回
-键值对的值。这些键值对是初始flags字典中两个元素的内容的逆。它们被送入dict构造函数。在这种情况下,dict构造函数的工作原理与上面的有所不同,因为构造函数被作为迭代器而不是字典作为参数。

借鉴@Chris Lutz的评论:如果您真的将它用于单字符值,则可以

>>> flags = {True: 'abc', False: 'de'}
>>> flags = dict(invert_dict(flags))
>>> print flags
{'a': True, 'c': True, 'b': True, 'e': False, 'd': False}

这是 可行的 ,因为Python字符串是
可迭代的
,这意味着它们可以逐值移动。对于字符串,值是字符串中的各个字符。因此,当它们被解释为可迭代时,例如在这种情况下,它们在for循环中使用,['a', 'b', 'c']并且'abc'实际上是等效的。另一个示例是将它们传递给需要迭代的函数时,例如tuple

我个人不会这样做,因为它不能直观地理解:当我看到一个字符串时,我希望它可以用作单个值而不是列表。因此,我看第一行,并认为“好吧,所以有一个True标志和一个False标志。”
因此,尽管有可能,但我不认为这是可行的方法。从好的方面来说,这可能有助于更清楚地解释可迭代和迭代器的概念。

定义函数invert_dict以使其实际上返回字典也不是坏主意。我大多只是不这样做,因为它并不能真正帮助解释例程的工作原理。

显然,Python 2.7具有字典理解功能,这将为实现该功能提供一种极为简洁的方法。这留给读者练习,因为我没有安装Python 2.7 :)

您还可以结合功能广泛的itertools模块中的某些功能。正如他们所说,做到这一点不止一种方法。等等,Python人士不这么说。好吧,在某些情况下还是如此。我猜想圭多(Guido)已经给了我们字典理解能力,因此会有一种明显的方式来做到这一点。



 类似资料:
  • 问题内容: 我在Python中看到了这个声明,但是我不明白它的含义,也找不到解释: 问题是:和之间为什么会有逗号?那是什么类型的作业? 问题答案: 那是一个 “元组” 或 “解构” 分配- 参见例如多重分配语义。返回包含两个值的元组,因此等效于: 请参阅语言参考中的赋值语句: 如果目标列表是目标的逗号分隔列表:该对象必须是可迭代的,并且具有与目标列表中存在目标的项目数量相同的项目,并且这些项目从左

  • 问题内容: 在JavaScript中,可以这样声明多个变量: …或像这样: 一种方法比另一种更好/更快吗? 问题答案: 第一种方法更易于维护。每个声明都是一行上的单个语句,因此您可以轻松地添加,删除和重新排列声明。 使用第二种方法时,删除第一个或最后一个声明很烦人,因为它们包含关键字和分号。每次添加新的声明时,都必须将旧行中的分号更改为逗号。

  • 下面会对C语言、着色器语言ES GLSL、javascript语言和TypeScript语言声明变量的方式进行简单展示,这样可以更方便不同基础读者类比学习。 C语言 着色器语言ES GLSL和C语言有很多相似之处,如果你有一定的C语言基础,对于学习着色器语言也是有一定的帮助的。 // C语言声明一个整形变量并赋值10 int count = 10; // 改变变量值,重新赋值 count=20;

  • let和const是JavaScript里相对较新的变量声明方式。 像我们之前提到过的,let在很多方面与var是相似的,但是可以帮助大家避免在JavaScript里常见一些问题。 const是对let的一个增强,它能阻止对一个变量再次赋值。 因为TypeScript是JavaScript的超集,所以它本身就支持let和const。 下面我们会详细说明这些新的声明方式以及为什么推荐使用它们来代替v

  • 你好,Iam在spring(IntelliJ IDEA终极版)中使用AspectJ风格的AOP时遇到了麻烦。不使用方面时,输出与预期相同。但是当我将方面类受众声明为Bean时,我得到了Macbeth类的NoSuchBeanDefinitionException。 2017年8月27日上午9:38:39 org.springframework.context.annotationconfigappl

  • 从这节课开始我们就要正式开始学习 Go 语言的语法了,本文主要介绍了 Go 语言在代码中声明变量的几种方式,在 Go 语言中变量声明形式主要分为两种: 单变量声明 多变量声明 下面我们一一来看下这两种声明形式: 1. 单变量声明 Go 语言的变量声明需要使用关键字var,声明形式形如:var 变量名 变量类型,其中变量名由数字字母下划线组成,变量类型为 Go 语言内置支持的类型或者用户自定义类型。