要在“同一时间”声明多个变量,我会这样做:
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
或者我错过了什么?
答案 0 :(得分:203)
a, b, c, d, e, g, h, i, j = (True,)*9
f = False
答案 1 :(得分:48)
使用列表/字典或定义您自己的类来封装您正在定义的内容,但如果您需要所有这些变量,您可以这样做:
a = b = c = d = e = g = h = i = j = True
f = False
答案 2 :(得分:46)
正如其他人所建议的那样,使用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
等关键字参数覆盖字典的各个元素。上面的代码将**
后面的表达式的结果炸成一组传递给被调用函数的keyword arguments。这当然是创建字典的可靠方式,人们似乎至少接受了这个成语,但我怀疑有些人可能认为它是Unpythonic。 </disclaimer>
另一种方法,如果你经常使用这种模式,可能是最直观的,是将数据定义为映射到标志名称的标志值列表(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
是generator function。 生成或产生 - 意味着重复返回 - 键值对的值。这些键值对是初始flags
字典的两个元素的内容的倒数。它们被送入dict
构造函数。在这种情况下,dict
构造函数与上面的工作方式不同,因为它被赋予iterator而不是字典作为其参数。
借鉴@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字符串是iterable,这意味着它们可以通过值逐行移动。对于字符串,值是字符串中的单个字符。因此,当它们被解释为可迭代时,就像在for循环中使用它们的情况一样,['a', 'b', 'c']
和'abc'
实际上是等价的。另一个例子是当它们被传递给一个带有可迭代的函数,比如tuple
。
我个人不会这样做,因为它不直观地阅读:当我看到一个字符串时,我希望它被用作单个值而不是列表。所以我看第一行并想“好的,所以有一个真旗和一个假旗。”所以虽然这是一种可能性,但我认为这不是可行的方法。从好的方面来说,可以更清楚地解释迭代和迭代器的概念。
定义函数invert_dict
使其实际返回字典也不是一个坏主意;我大多只是不这样做,因为它没有真正帮助解释例程如何工作。
显然,Python 2.7具有字典理解,这将使得实现该功能的方式非常简洁。这是留给读者的练习,因为我没有安装Python 2.7:)
您还可以组合来自多功能itertools模块的一些功能。如他们所说,There's More Than One Way To Do It。等等,Python的人不这么说。嗯,在某些情况下无论如何都是如此。我猜想Guido已经给了我们字典理解,以便One Obvious Way能够做到这一点。
答案 3 :(得分:9)
这是关于@ Jeff M和我的评论的详细说明。
执行此操作时:
a, b = c, d
它适用于元组打包和拆包。您可以分开包装和拆包步骤:
_ = c, d
a, b = _
第一行创建一个名为_
的元组,它有两个元素,第一个元素的值为c
,第二个元素的值为d
。第二行将_
元组解压缩到变量a
和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 = _
它将为您提供与第一行完全相同的结果(如果您将值或变量添加到一个部分但忘记更新另一个部分,则包括相同的异常)。 但是,在这种特定情况下,yan's answer可能是最好的。
如果您有值列表,仍可以解压缩它们。你只需要先将其转换为元组。例如,以下内容将分别为a
到j
分配0到9之间的值:
a, b, c, d, e, f, g, h, i, j = tuple(range(10))
编辑:除了元素5(变量f
)之外,将所有这些都分配为真的技巧:
a, b, c, d, e, f, g, h, i, j = tuple(x != 5 for x in range(10))
答案 4 :(得分:5)
当人们建议“使用列表或元组或其他数据结构”时,他们所说的是,当您有许多不同的值时,将它们全部命名为局部变量可能不是做事的最佳方式。
相反,您可能希望将它们聚集在一起,形成一个可以存储在单个局部变量中的更大的数据结构。
intuited展示了如何使用字典,Chris Lutz展示了如何在解压缩到单独的变量之前使用元组进行临时存储,但另一个需要考虑的选择是使用collections.namedtuple
来捆绑更多的值永久
所以你可以这样做:
# Define the attributes of our named tuple
from collections import namedtuple
DataHolder = namedtuple("DataHolder", "a b c d e f g")
# Store our data
data = DataHolder(True, True, True, True, True, False, True)
# Retrieve our data
print(data)
print(data.a, data.f)
当然,真正的代码可能会使用比“DataHolder”和字母表字母更有意义的名称。
答案 5 :(得分:4)
事实上,问题是什么?
如果您确实需要或想要10 a , b , c , d , e , f , g , h ,我, j ,在这个或那个时间,没有其他可能写 a 并写 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]
也就是说单独定义“变量”。
或者,使用其他写作,无需使用_
:
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
时,就不会在“值可以改变的内存块”意义上创建一个变量。这条指令:
触发创建类型为integer
且值为10的对象,并在当前命名空间中将名称“a”与此对象绑定
或将名称空间中的名称“a”重新指定给对象 10 (因为'a'先于绑定到另一个对象)
我这样说是因为我没有看到实用程序定义10个标识符a,b,c ...指向False或True。如果这些值在执行期间没有改变,为什么有10个标识符呢?如果它们发生变化,为什么首先定义标识符?,如果没有事先定义,它们将在需要时创建
你的问题对我来说很奇怪
答案 6 :(得分:2)
听起来你正以错误的方式接近你的问题。
重写代码以使用元组或编写类来存储所有数据。
答案 7 :(得分:1)
在您的情况下,我将使用YAML。
这是处理多个参数的一种优雅而专业的标准。 这些值是从单独的文件加载的。 您可以在此链接中看到一些信息:
https://keleshev.com/yaml-quick-introduction
但是对于Google来说,它比较容易,因为它是一种标准,有成百上千的信息,您可以找到最适合您的理解的信息。 ;)
最诚挚的问候。
答案 8 :(得分:0)
我喜欢最高投票的答案;但是,如图所示,列表存在问题。
>> a, b = ([0]*5,)*2
>> print b
[0, 0, 0, 0, 0]
>> a[0] = 1
>> print b
[1, 0, 0, 0, 0]
我们详细讨论了这一问题(here),但要点是a
和b
是a is b
返回True
的同一个对象(相同的id(a) == id(b)
)。因此,如果您更改索引,则会更改a
和b
的索引,因为它们已关联。要解决此问题,您可以执行(source)
>> 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]
然后可以将其用作最佳答案的变体,其具有&#34;期望的&#34;直观的结果
>> a, b, c, d, e, g, h, i = (True for i in range(9))
>> f = (False for i in range(1)) #to be pedantic
答案 9 :(得分:0)
像 JavaScript 一样,您还可以在python a = 1; b = "Hello World"; c += 3