简体   繁体   English

Python高阶序列赋值?

[英]Python higher-order sequence assignment?

Is there a way to group names together in python, to repeatedly assign to them en masse ? 有没有一种方法,以组名一起蟒蛇,反复为他们分配集体

While we can do: 我们可以这样做:

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

I would like to be able to do something like: 我希望能够做到这样的事情:

names = a,b,c

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

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

Is there a built-in syntax for this? 这是否有内置语法? If not, I assume it would be possible with an object that overloads its assignment operator. 如果没有,我认为对象可能会重载其赋值运算符。 In that case, is there an existing implementation, and would this concept have any unexpected failure modes? 在这种情况下,是否存在现有实现,并且此概念是否会出现任何意外故障模式?

The point is not to use the names as data, but rather to be able to use the actual names as variables that each refer to their own individual item, and to be able to use the list as a list, and to avoid code like: 关键是不要将名称用作数据,而是能够将实际名称用作每个引用其各自项目的变量,并且能够将列表用作列表,并避免代码如下:

a = 1
b = 2
c = 3

sequence = (a,b,c)

You should go one level up in your data abstraction. 你应该在数据抽象中提升一级。 You are not trying to access the entries by their individual names -- you rather use names to denote the whole collection of values, so a simple list might be what you want. 您不是试图通过各自的名称来访问条目 - 您更愿意使用names来表示整个值集合,因此您可以使用简单的列表。

If you want both, a name for the collection and names for the individual items, then a dictionary might be the way to go: 如果你想同时,收集名称的个别项目的名称,然后字典可能是要走的路:

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

If you need something like this repeatedly, you might want to define a class with the names as attributes: 如果您需要重复这样的事情,您可能希望定义一个名称为属性的类:

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

This reflects that you want to block a , b and c to some common structure, but keep the option to access them individually by name. 这反映出您想要阻止abc到某个常见结构,但保留选项以按名称单独访问它们。

You should use a dict : 你应该使用一个dict

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

I've realised that "exotic" syntax is probably unnecessary. 我意识到“异国情调”的语法可能是不必要的。 Instead the following achieves what I wanted: (1) to avoid repeating the names and (2) to capture them as a sequence: 相反,以下内容实现了我想要的:(1)避免重复名称和(2)将它们捕获为序列:

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

Of course, this won't allow: 当然,这不允许:

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

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

So, it won't facilitate repeated assignment to the same group of names without writing out those names repeatedly (except in a loop). 因此,它不会在不重复写出这些名称的情况下重复分配给同一组名称(循环除外)。

This? 这个?

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

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

Well, you shouldn't do this, since it's potentially unsafe, but you can use the exec statement 好吧,你不应该这样做,因为它可能不安全,但你可以使用exec语句

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

Python has such an elegant namespace system: 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()

Each instance of GenericContainer is an isolated namespace. GenericContainer的每个实例都是一个独立的命名空间。 IMHO it is better than messing with the local namespace even if you are programming under a pure procedural paradigm. 恕我直言,即使你是在一个纯粹的程序范式下进行编程,也比搞乱本地命名空间更好。

Not sure whether this is what you want... 不确定这是否是你想要的......

>>> 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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM