更优雅的方式来同时声明多个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)的标志值列表( True
, False
)。 然后,将这个数据定义转换成一个将标志名称映射为标志值的反转字典。 这可以用嵌套的列表理解相当简洁地完成,但是这里有一个非常可读的实现:
>>> 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解包到variablesa
和b
。 这打破了你的一个巨大的线:
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之间的值分配给a
到j
每a
:
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 a , b , c , d , e , f , g , h , i , j ,那么在这个或者那个时间里就没有其他的可能性来写和写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]
这里详细讨论了这个问题,但要点是a
和b
是同一个对象,而b
是返回True
( id(a) == id(b)
)。 因此,如果更改索引,则会更改a
和b
的索引,因为它们已链接。 要解决这个问题,你可以做(源)
>> 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