更优雅的方式来同时声明多个variables

要在“同一时间”声明多个variables,我会这样做:

a, b = True, False 

但是,如果我不得不申报更多的variables,那么变得越来越不优雅:

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

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

提前致谢!

编辑:

这一定是非常基本的,但是如果我使用了一个列表或者一个元组来存储这些variables,那么我将如何处理这个问题,这样我才会有帮助:

 aList = [a,b] 

是无效的,我将不得不这样做:

 a, b = True, True 

或者我错过了什么?

正如其他人所build议的那样,使用10个不同的布尔值局部variables不太可能是编写例程的最好方法(特别是如果他们真的只有一个字母名称:)

根据你在做什么,它可能是有道理的,而不是使用字典。 例如,如果要为一组单字母标志设置布尔预设值,则可以这样做:

 >>> 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的第二个参数并不是完全为此devise的:它的意思是允许你使用关键字参数(如d=False覆盖字典中的单个元素。 上面的代码将下面的expression式的结果放到一组传递给被调用函数的关键字参数中。 这当然是制作字典的可靠方法,人们似乎至less接受了这个成语,但我怀疑有些人可能认为它是Unpythonic。 </disclaimer>


如果您经常使用这种模式,另一种方法可能是最直观的,那就是将您的数据定义为映射到标志名称(单字符string)的标志值列表( 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} 

这是可行的 ,因为Pythonstring是可迭代的 ,这意味着它们可以通过值来移动。 在string的情况下,值是string中的单个字符。 所以当它们被解释为可迭代的时候,就像在这种情况下它们被用在for循环中一样, ['a', 'b', 'c']'abc'实际上是等价的。 另一个例子是当他们被传递给一个需要迭代的函数时,比如tuple

我个人不会这样做,因为它不会直观地读取:当我看到一个string时,我期望它被用作单个值而不是列表。 所以我看着第一行,想:“好吧,真旗子,假旗子。” 所以尽pipe这是可能的,但我不认为这是一条可行的路。 另一方面,这可能有助于更清楚地解释迭代器和迭代器的概念。


定义函数invert_dict ,使其实际返回一个字典也不是一个坏主意; 我主要是没有这样做,因为它没有真正帮助解释例程的工作方式。


显然Python 2.7有字典parsing,这将使一个非常简洁的方式来实现该function。 这是留给读者的一个练习,因为我没有安装Python 2.7

您还可以结合使用多functionitertools模块的一些function。 正如他们所说, 有不止一个方法去做 。 等等,Python的人不会这么说的。 好吧,在某些情况下是这样的。 我猜想,圭多给了我们字典的理解,以便有一个明显的方法来做到这一点。

 a, b, c, d, e, g, h, i, j = (True,)*9 f = False 

使用一个列表/字典或定义你自己的类来封装你定义的东西,但是如果你需要所有这些variables你可以做:

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

这是对@ Jeff M和我的评论的阐述。

当你这样做:

 a, b = c, d 

它适用于元组打包和解包。 您可以分开包装和拆包步骤:

 _ = c, d a, b = _ 

第一行创build一个名为_的元组,它有两个元素,第一个元素的值为c ,第二个元素的值为d 。 第二行将_ tuple解包到variablesab 。 这打破了你的一个巨大的线:

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

分成两个较小的行:

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

它会给你与第一行完全相同的结果(包括如果你将值或variables添加到一个部分但忘记更新另一部分的情况下也是如此)。 然而,在这个特定的情况下, 颜的答案也许是最好的。

如果你有一个值列表,你仍然可以解压缩它们。 你只需要把它转换成一个元组。 例如,以下将分别为0到9之间的值分配给aja

 a, b, c, d, e, f, g, h, i, j = tuple(range(10)) 

编辑:整洁的把戏,除了元素5(variablesf ),将其全部赋值为true:

 a, b, c, d, e, f, g, h, i, j = tuple(x != 5 for x in range(10)) 

当人们build议“使用列表或元组或其他数据结构”时,他们所说的是,当你有许多不同的值时,你把它们分别命名为局部variables可能不是最好的方法做事。

相反,您可能希望将它们聚集到一个更大的数据结构中,该数据结构可以存储在一个局部variables中。

直觉地展示了如何使用字典,Chris Lutz展示了如何在解压到单独的variables之前使用一个元组来进行临时存储,但是另一种select是使用collections.namedtuple来更持久地绑定这些值。

所以你可能会这样做:

 # Define the attributes of our named tuple from collections import namedtuple DataHolder = namedtuple("DataHolder", "abcdefg") # Store our data data = DataHolder(True, True, True, True, True, False, True) # Retrieve our data print(data) print(data.a, data.f) 

当然,真正的代码希望使用比“DataHolder”和字母表更有意义的名字。

问题其实是什么?

如果你真的需要或者想要10 abcdefghij ,那么在这个或者那个时间里就没有其他的可能性来写和写b和写c了 。 ….

如果这些数值都是不同的,那么你将不得不写作例子

 a = 12 b= 'sun' c = A() #(where A is a class) d = range(1,102,5) e = (line in filehandler if line.rstrip()) f = 0,12358 g = True h = random.choice i = re.compile('^(!= ab).+?<span>') j = [78,89,90,0] 

也就是说分别定义“variables”。

或者,使用另一种写法,不需要使用_

 a,b,c,d,e,f,g,h,i,j =\ 12,'sun',A(),range(1,102,5),\ (line for line in filehandler if line.rstrip()),\ 0.12358,True,random.choice,\ re.compile('^(!= ab).+?<span>'),[78,89,90,0] 

要么

 a,b,c,d,e,f,g,h,i,j =\ (12,'sun',A(),range(1,102,5), (line for line in filehandler if line.rstrip()), 0.12358,True,random.choice, re.compile('^(!= ab).+?<span>'),[78,89,90,0]) 

如果他们中的一些人必须具有相同的价值,那么写这个问题太长了

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

那么你可以写:

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

我不明白什么是你的问题。 如果你想写一个代码,你必须使用指令和定义所需的字符。 还有什么 ?

我想知道你的问题是不是你误解了什么的迹象。

当写a = 10就不会创build一个 “值可以改变的内存块”意义上的variables 。 这条指令:

  • 要么触发创build一个types为integer和值为10的对象,并且在当前名称空间中将该对象与名称“a”绑定

  • 或者将名称空间中的名称“a”重新分配给对象10 (因为“a”先前被绑定到另一个对象)

我说,因为我没有看到实用程序定义10个标识符a,b,c …指向False或True。 如果这些值在执行过程中不改变,为什么10个标识符? 如果他们改变了,为什么首先定义标识符?如果没有事先定义,他们将在需要时被创build

你的问题对我来说很奇怪

听起来像是你正在接近你的问题对我来说是错误的。

重写你的代码来使用一个元组或写一个类来存储所有的数据。

我喜欢顶尖的投票答案; 但是,它显示的列表有问题。

  >> a, b = ([0]*5,)*2 >> print b [0, 0, 0, 0, 0] >> a[0] = 1 >> print b [1, 0, 0, 0, 0] 

这里详细讨论了这个问题,但要点是ab是同一个对象,而b是返回Trueid(a) == id(b) )。 因此,如果更改索引,则会更改ab的索引,因为它们已链接。 要解决这个问题,你可以做(源)

 >> a, b = ([0]*5 for i in range(2)) >> print b [0, 0, 0, 0, 0] >> a[0] = 1 >> print b [0, 0, 0, 0, 0] 

这可以作为顶级答案的变体,它具有“理想的”直观结果

 >> a, b, c, d, e, g, h, i = (True for i in range(9)) >> f = (False for i in range(1)) #to be pedantic