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