Python 如何获取列表元素的引用?

Python 如何获取列表元素的引用?,python,Python,是否可以从列表中获取一个元素的引用 我知道如何将一个完整的列表引用到另一个列表: 但是我怎样才能得到一个元素的引用呢? 例如: 或者在python中还有其他解决方案吗?这是不可能的,因为整数是不可变的,而列表是可变的 在b=a[1]中,您实际上是在给b 演示: 你可以像这样 >>> a = [1,2,3] >>> b = a >>> a[1] = 3 >>> b [1, 3, 3] >>> a [1,

是否可以从列表中获取一个元素的引用

我知道如何将一个完整的列表引用到另一个列表:

但是我怎样才能得到一个元素的引用呢? 例如:


或者在python中还有其他解决方案吗?

这是不可能的,因为整数是不可变的,而列表是可变的

b=a[1]
中,您实际上是在给
b

演示:

你可以像这样

>>> a = [1,2,3]
>>> b = a
>>> a[1] = 3
>>> b
[1, 3, 3]
>>> a
[1, 3, 3]
>>> id(a)
140554771954576
>>> id(b)
140554771954576

似乎您需要在需要时重新定义b=a[1],或者使用a[1]。如上所述,整数与列表不同是不可变的——我不会重复其他人所说的,因此不会起作用。我建议只在需要的地方使用[1],或者为长行的可读性重新指定b=a[1]

由于我的误解,下面回答了错误的问题:

定义b时,可以使用
*
运算符

a = [1,2,3]
b = 1*a #my book says *a will work, but it creates an error in spyder when I tested it

b
>>> [1,2,3]

a[1] = 3

a
>>> [1,3,3]

b
>>> [1,2,3]

来源:我的编程课程

您不能将变量的引用指定给列表位置。与C++不同,在Python中这是不可能的。最接近的方法是创建一个匿名函数来引用单个列表索引,并为其指定一个新值:

>>> L = [1,2,3]
>>> def itemsetter(L, pos):
...     def inner(x):
...             L[pos] = x
...     return inner
... 
>>> f = itemsetter(L, 1)
>>> f
<function inner at 0x7f9e11fa35f0>
>>> f(9)
>>> L
[1, 9, 3]
您可以创建自定义类,而不是列表:

>>> class wrap:
...     def __init__(self, value):
...             self.value = value
... 
>>> L3 = [wrap(x) for x in L]
>>> L3
[<__main__.wrap instance at 0x7feca2c92ab8>, <__main__.wrap instance at 0x7feca2c92b00>, <__main__.wrap instance at 0x7feca2c92b48>]
>>> A = L3[1]
>>> A.value = 9
>>> L3[1].value
9
>>> L3[0].value
1
>>> L3[2].value
3
>>类换行:
...     定义初始值(自身,值):
...             自我价值=价值
... 
>>>L3=[在L中为x换行(x)]
>>>L3
[, ]
>>>A=L3[1]
>>>A.数值=9
>>>L3[1]。值
9
>>>L3[0]。值
1.
>>>L3[2]。值
3.

正如Jornsharpe所说,你可以通过在列表中使用可变元素来做你想做的事情,例如让列表元素自己列表

比如说

a = [[i] for i in xrange(5)]
print a

b = a[3]
print b[0]


a[3][0] = 42

print a
print b[0]


b[:] = [23]

print a
print b
输出

[[0], [1], [2], [3], [4]]
3
[[0], [1], [2], [42], [4]]
42
[[0], [1], [2], [23], [4]]
[23]

Python是一种具有一流函数的面向对象语言。它不像C那样处理指针。列表条目本身不是对象,因此您需要同时保存一个条目索引和一个对容器的引用,才能执行您描述的插槽处理。例如,有一些包可以这样做,即numpy,但它需要一层间接寻址,因为形式为
foo=something
的赋值将绑定名称foo,而不是修改foo用来引用的内容

以下是此类间接类的一个示例:

class Indirect(object):
    def __init__(self, container, item):
        self.container = container
        self.item = item
    @property
    def value(self):
        return self.container[self.item]
    @value.setter
    def value(self, value):
        self.container[self.item] = value

l = [1,2,3]
ref = Indirect(l, 1)
ref.value = 5
print(l)
第一类函数支持意味着您还可以为所需的特定任务动态创建函数:

l = [1,2,3]
def callwith5(func):    # doesn't know what func does
    return func(5)
setanitem = lambda i: l[1]=i    # creates a new function
callwith5(setanitem)
print(l)
表达这种差异的另一种方式是Python在C术语中并没有真正的
lvalue
;我们只有几个语法扩展,可以将赋值语句转换为不同的调用:

a = 1      # if a is global:  setitem(globals(), 'a', 1)
a = 1      # otherwise:       setitem(locals(), 'a', 1)
foo.a = 1  # setattr(foo, 'a', 1)  => foo.__setattr__('a', 1)
l[1] = 5   # setitem(l, 1, 5)      => l.__setitem__(1, 5)

它们中的许多都经过了优化,因此不需要查找setitem、setattr等,而它们又有一组规则,这些规则引用了一些特定的方法,如
\uuuuuu setitem\uuuuuuuu
\uuuuuu setattr\uuuuuuuuu
,但最终的规则是,所有内容都是通过某个对象访问的,根是模块字典

在Python中,一切都是对象,包括数字。数字是不可变的对象,它们只存在一次。换句话说,在上面的示例中,
a
不包含值2,它包含对表示整数2的
Number
对象的引用。这很容易验证:

a = 2 # reference to the object that represents integer 2
print type(2), type(a), isinstance(2, Number), isinstance(a, Number)
=> <type 'int'> <type 'int'> True True
我们现在可以回答您的问题:

但是我怎样才能得到一个元素的引用呢

您已经获得了对元素的引用:

a = [1,2,3]
b = []
b = a[1] 
a[1] = 3
print (b) #b is now 2, but I want the value 3 like it is in a[1]
=> 2
print id(a[1]), id(b), id(2)
=> 4301262984 4301263008 4301263008
Python列表始终存储对象引用。通过设置
a[1]=3
您实际上是在将第二个列表元素引用的内容从id(2)更改为id(3)
b
继续(正确地)保留对对象id(2)的引用,这是您要求它执行的操作

是否有办法实现您想要的,即让
b
以某种方式指向
a[1]
的当前值?我想到了两个选择:

  • 存储元素的索引,而不是其值:

    a = [1,2,3]
    b = []
    b = a  # reference the list
    b_i = 1  # reference the index
    a[1] = 3 # change value at index 1
    print (b[b_i]) 
    => 3
    a[1] = 4
    print (b[b_i])
    => 4
    
  • 在列表中,存储对象并更改这些对象的值:

    class Element(int):
        def __init__(self, value):
            self.value = value
        def __str__(self):
            return "%s" % self.value
        def __repr__(self):
            return "%s" % self.value
    a = [Element(n) for n in [1,2,3]]
    print a
    => [1, 2, 3]
    b = a[1] 
    a[1].value = 3 # don't change a[1]'s reference, change its value!
    print (b) 
    => 3
    print id(a[1]), id(b) # same object
    => 4372145648 4372145648
    
    class Article(object):
        def __init__(self, title):
            self.title = title
            self.users = []
    
    the_articles = [Article("How to cook"), Article("Latest News")]
    

  • 你可以做你想做的事。你最初的问题涉及整数,但你真正的问题不是。询问你的真实情况会得到更好的答案

    你说

    我想生成两个类列表

    我想你指的是物体。然后:

    一个带有用户类的“全局”列表和另一个带有文章类的列表。每篇文章都应该有一个对本文感兴趣的“本地”用户列表。但是这个本地列表应该只指向“全局”用户列表的一个子集

    您可以创建用户对象列表:

    class User(object):
        def __init__(self, name):
            self.name = name
            self.karma = 0
    
    the_users = [User('Ned'), User('char0n'), User('Mithu')]
    
    您可以创建项目对象列表:

    class Element(int):
        def __init__(self, value):
            self.value = value
        def __str__(self):
            return "%s" % self.value
        def __repr__(self):
            return "%s" % self.value
    a = [Element(n) for n in [1,2,3]]
    print a
    => [1, 2, 3]
    b = a[1] 
    a[1].value = 3 # don't change a[1]'s reference, change its value!
    print (b) 
    => 3
    print id(a[1]), id(b) # same object
    => 4372145648 4372145648
    
    class Article(object):
        def __init__(self, title):
            self.title = title
            self.users = []
    
    the_articles = [Article("How to cook"), Article("Latest News")]
    
    您可以将用户与文章关联:

    the_articles[0].users.append(the_users[0])
    the_articles[1].users.append(the_users[0])
    the_articles[1].users.append(the_users[1])
    
    现在,文章的用户列表引用用户列表中的用户对象。如果修改用户,则可以通过以下文章看到:

    the_users[1].karma += 10
    print sum(u.karma for u in the_articles[1].users)
    

    <代码> A= B<代码>,名称为<代码> A/Eng>,引用对象<代码> b>代码>不同于C/C++ +强>不修改<<代码> < < /> > > >/P>之前的对象

    >>> a = 2
    >>> id(a)
    505493912
    >>> a = 3
    >>> id(a)
    505493928
    
    a
    引用的对象未更改<代码>一个开始引用不同的对象

    直接来说,这是不可能的,但是很少有解决办法,比如在

    还有另一个解决办法: #用法:


    不,您描述的行为在Python.Ok中是不可能的。对于指向相同值的两个列表,没有其他可能性。但是一个列表只是另一个列表的子集。仅当列表中的值是可变的时。到坏。我想生成两个类列表。一个带有用户类的“全局”列表和另一个带有文章类的列表。每篇文章都应该有一个对本文感兴趣的“本地”用户列表。但是这个本地列表应该只指向“全局”用户列表中的一部分用户。Python是一种解释性脚本语言,您要做的事情需要更多的“编译”类型的语言,比如C/C++语言,您可以使用指针引用内存位置。也许你是在尝试t
    the_articles[0].users.append(the_users[0])
    the_articles[1].users.append(the_users[0])
    the_articles[1].users.append(the_users[1])
    
    the_users[1].karma += 10
    print sum(u.karma for u in the_articles[1].users)
    
    >>> a = 2
    >>> id(a)
    505493912
    >>> a = 3
    >>> id(a)
    505493928
    
    def overload(*functions):
        return lambda *args, **kwargs: functions[len(args)](*args, **kwargs)
    
    class Ref:
        def __init__(self, new_target):
            self.target=new_target
        def __repr__(self):
            return 'Ref(' + repr(self.target) + ')'
        __call__=overload(None, lambda self: self.target, __init__)
    
    >>> a = [Ref(1), Ref(2), Ref(3)]
    >>> b = a[1]
    >>> print(b)
    Ref(2)
    >>> a[1](3)
    >>> print(b)
    Ref(3)
    >>> print(b())
    3