Python高阶序列赋值?

时间:2012-02-24 15:09:57

标签: python syntax programming-languages

有没有办法在python中将名称组合在一起,重复分配给它们 en masse

虽然我们可以做到:

a,b,c = (1,2,3)

我希望能够做到这样的事情:

names = a,b,c

*names = (3,2,1) # this syntax doesn't work

a,b,c == (3,2,1) #=> True

这是否有内置语法?如果没有,我认为对象可能会重载其赋值运算符。在这种情况下,是否存在现有实现,并且此概念是否会出现任何意外的故障模式?

关键是不要将名称用作数据,而是能够将实际名称用作每个引用其各自项目的变量,并且能够将列表用作列表,并避免代码如:

a = 1
b = 2
c = 3

sequence = (a,b,c)

7 个答案:

答案 0 :(得分:2)

你应该在数据抽象中提升一级。您不是试图通过各自的名称访问条目 - 您宁愿使用names来表示整个值集合,因此可能是您想要的简单列表。

如果你想要两个,一个名称的集合名称的单个项目,那么字典可能是要走的路:

names = "a b c".split()
d = dict(zip(names, (1, 2, 3)))
d.update(zip(names, (3, 2, 1)))

如果你需要重复这样的东西,你可能想要定义一个名为属性的类:

class X(object):
    def __init__(self, a, b, c):
        self.update(a, b, c)
    def update(self, a, b, c)
        self.a, self.b, self.c = a, b, c

x = X(1, 2, 3)
x.update(3, 2, 1)
print x.a, x.b. x.c

这反映出您希望阻止abc加入某个常见结构,但保留按名称单独访问它们的选项。

答案 1 :(得分:1)

您应该使用dict

>>> d = {"a": 1, "b": 2, "c": 3}
>>> d.update({"a": 8})
>>> print(d)
{"a": 8, "c": 3, "b": 2}

答案 2 :(得分:1)

我意识到“异国情调”的语法可能是不必要的。相反,以下实现了我想要的:(1)避免重复名称和(2)将它们捕获为序列:

sequence = (a,b,c) = (1,2,3)

当然,这不允许:

*names = (3,2,1) # this syntax doesn't work

a,b,c == (3,2,1) #=> True

因此,如果不重复写出这些名称(循环除外),它不会有助于重复分配到同一组名称。

答案 3 :(得分:1)

此?

>>> from collections import namedtuple
>>> names = namedtuple( 'names', ['a','b','c'] )

>>> thing= names(3,2,1)
>>> thing.a
3
>>> thing.b
2
>>> thing.c
1

答案 4 :(得分:0)

嗯,你不应该这样做,因为它可能不安全,但你可以use the exec statement

>>> names = "a, b, c"
>>> tup = 1,2,3
>>> exec names + "=" + repr(tup)
>>> a, b, c
(1, 2, 3)

答案 5 :(得分:0)

Python拥有如此优雅的命名空间系统:

#!/usr/bin/env python

class GenericContainer(object):
    def __init__(self, *args, **kwargs):
        self._names = []
        self._names.extend(args)
        self.set(**kwargs)
    def set(self, *args, **kwargs):
        for i, value in enumerate(args):
            self.__dict__[self._names[i]] = value
        for name, value in kwargs.items():
            if name not in self._names:
                self._names.append(name)
            self.__dict__[name] = value
    def zip(self, names, values):
        self.set(**dict(zip(names, values)))

def main():
    x = GenericContainer('a', 'b', 'c')
    x.set(1, 2, 3, d=4)
    x.a = 10
    print (x.a, x.b, x.c, x.d,)
    y = GenericContainer(a=1, b=2, c=3)
    y.set(3, 2, 1)
    print (y.a, y.b, y.c,)
    y.set(**dict(zip(('a', 'b', 'c'), (1, 2, 3))))
    print (y.a, y.b, y.c,)
    names = 'x', 'y', 'z'
    y.zip(names, (4, 5, 6))
    print (y.x, y.y, y.z,)

if __name__ == '__main__':
    main()

GenericContainer的每个实例都是一个独立的命名空间。恕我直言,即使你是在一个纯粹的程序范式下进行编程,也不如搞乱本地命名空间。

答案 6 :(得分:-1)

不确定这是否是你想要的......

>>> a,b,c = (1,2,3)
>>> names = (a,b,c)
>>> names
(1, 2, 3)
>>> (a,b,c) == names
True
>>> (a,b,c) == (1,2,3)
True