是否可以使用 python 中的元组索引嵌套列表?
Is it possible to index nested lists using tuples in python?
我刚开始使用 python,很快就想知道是否可以用元组索引嵌套列表。类似于:elements[(1,1)]
我想做的一个例子类似于下面的代码,我在其中保存了矩阵的一些位置,稍后我将需要在一个名为 index 的元组中访问这些位置。
index = ( (0,0), (0,2), (2,0), (2,2) )
elements = [ [ 'a', 'b', 'c'],
[ 'c', 'd', 'e'],
[ 'f', 'g', 'h'] ]
for i in index:
print (elements [ i[0] ] [ i[1] ])
# I would like to do this:
# print(elements[i])
这似乎是一个有用的功能。有什么办法吗?或者也许是一个简单的替代方案?
是的,你可以做到。我写了一个类似的例子:
index = [ [0,0], [0,2], [2,0], [2,2] ]
elements = [ [ 'a', 'b', 'c'],
[ 'c', 'd', 'e'],
[ 'f', 'g', 'h'] ]
for i,j in index:
print (elements [ i ] [ j ])
a c f h
# I would like to do this:
# print(elements[i])
不可以,您不能以这种方式为嵌套列表的特定值编制索引。
唯一稍微好一点的方法是 "unpack" 元组是否在迭代它们:
示例:
for i, j in index:
print(elements[i][j])
如果要打印元素中的所有内容
index = ( (0,0), (0,2), (2,0), (2,2) )
elements = [ [ 'a', 'b', 'c'],
[ 'c', 'd', 'e'],
[ 'f', 'g', 'h'] ]
for row in elements:
for i in range(len(row)):
print (row[i])
如果您真的想使用元组进行索引,您可以实现自己的 class 扩展 list
并重新定义 __getattr__
以使用元组并使用它:
class TList(list):
def __getitem__(self, index):
if hasattr(index, "__iter__"):
# index is list-like, traverse downwards
item = self
for i in index:
item = item[i]
return item
# index is not list-like, let list.__getitem__ handle it
return super().__getitem__(index)
elements = TList([ [ 'a', 'b', 'c'],
[ 'c', 'd', 'e'],
[ 'f', 'g', 'h'] ])
index = ( (0,0), (0,2), (2,0), (2,2) )
for i in index:
print(elements[i])
a
c
f
h
您可以使用列表理解:
index = ((0, 0), (0, 2), (2, 0), (2, 2))
elements = [['a', 'b', 'c'],
['c', 'd', 'e'],
['f', 'g', 'h']]
tmp = [print(elements[i][j]) for i,j in index]
这里有一些在事先不知道维度的情况下也能奏效的答案。
递归版本:
def multiget_rec(arr, *indices):
if len(indices)==0:
return arr
return multiget_rec(arr[indices[0]], *indices[1:])
程序化版本:
def multiget_proc(arr, *indices):
while len(indices)>0:
i, *indices = indices
arr = arr[i]
return arr
还有一个基于 reduce 的版本可以用作 1-liner:
from functools import reduce
def multiget_reduce(arr, *indices):
return reduce(lambda a,i:a[i], indices, arr)
都可以这样称呼
for i in index:
print (multiget(elements, *i))
编辑:
使用 reduce 似乎是三种方法中最快的,至少对于小型数组而言。我也觉得它看起来最干净
$ python -m timeit -s "def multiget_rec(arr, *indices):" \
-s " if len(indices)==0: return arr" \
-s " return multiget_rec(arr[indices[0]], *indices[1:])" \
-- "d = [[[3]]]" \
"multiget_rec(d, 0,0,0)"
500000 loops, best of 5: 941 nsec per loop
$ python -m timeit -s "def multiget_proc(arr, *indices):" \
-s " while len(indices)>0:" \
-s " i, *indices = indices" \
-s " return arr" \
-s "d = [[[3]]]" \
-- "multiget_proc(d, 0,0,0)"
500000 loops, best of 5: 529 nsec per loop
$ python -m timeit -s "from functools import reduce" \
-s "def multiget_reduce(arr, *indices):" \
-s " return reduce(lambda a,i:a[i], indices, arr)" \
-s "d = [[[3]]]" \
-- "multiget_reduce(d, 0,0,0)"
1000000 loops, best of 5: 384 nsec per loop
我知道这个问题是 6 年前的,但是
我的解决方案可能仍然有用。 (或不)
解法:
the_func = lambda func, index1, index2: func[index1][index2]
func = [[1,2,3,4],[5,6,7,8]]
index = [(1, 1), (0, 1)] # [6, 2]
print(the_func(func, *index[0]))
我刚开始使用 python,很快就想知道是否可以用元组索引嵌套列表。类似于:elements[(1,1)]
我想做的一个例子类似于下面的代码,我在其中保存了矩阵的一些位置,稍后我将需要在一个名为 index 的元组中访问这些位置。
index = ( (0,0), (0,2), (2,0), (2,2) )
elements = [ [ 'a', 'b', 'c'],
[ 'c', 'd', 'e'],
[ 'f', 'g', 'h'] ]
for i in index:
print (elements [ i[0] ] [ i[1] ])
# I would like to do this:
# print(elements[i])
这似乎是一个有用的功能。有什么办法吗?或者也许是一个简单的替代方案?
是的,你可以做到。我写了一个类似的例子:
index = [ [0,0], [0,2], [2,0], [2,2] ]
elements = [ [ 'a', 'b', 'c'],
[ 'c', 'd', 'e'],
[ 'f', 'g', 'h'] ]
for i,j in index:
print (elements [ i ] [ j ])
a c f h
# I would like to do this: # print(elements[i])
不可以,您不能以这种方式为嵌套列表的特定值编制索引。
唯一稍微好一点的方法是 "unpack" 元组是否在迭代它们:
示例:
for i, j in index:
print(elements[i][j])
如果要打印元素中的所有内容
index = ( (0,0), (0,2), (2,0), (2,2) )
elements = [ [ 'a', 'b', 'c'],
[ 'c', 'd', 'e'],
[ 'f', 'g', 'h'] ]
for row in elements:
for i in range(len(row)):
print (row[i])
如果您真的想使用元组进行索引,您可以实现自己的 class 扩展 list
并重新定义 __getattr__
以使用元组并使用它:
class TList(list):
def __getitem__(self, index):
if hasattr(index, "__iter__"):
# index is list-like, traverse downwards
item = self
for i in index:
item = item[i]
return item
# index is not list-like, let list.__getitem__ handle it
return super().__getitem__(index)
elements = TList([ [ 'a', 'b', 'c'],
[ 'c', 'd', 'e'],
[ 'f', 'g', 'h'] ])
index = ( (0,0), (0,2), (2,0), (2,2) )
for i in index:
print(elements[i])
a
c
f
h
您可以使用列表理解:
index = ((0, 0), (0, 2), (2, 0), (2, 2))
elements = [['a', 'b', 'c'],
['c', 'd', 'e'],
['f', 'g', 'h']]
tmp = [print(elements[i][j]) for i,j in index]
这里有一些在事先不知道维度的情况下也能奏效的答案。
递归版本:
def multiget_rec(arr, *indices):
if len(indices)==0:
return arr
return multiget_rec(arr[indices[0]], *indices[1:])
程序化版本:
def multiget_proc(arr, *indices):
while len(indices)>0:
i, *indices = indices
arr = arr[i]
return arr
还有一个基于 reduce 的版本可以用作 1-liner:
from functools import reduce
def multiget_reduce(arr, *indices):
return reduce(lambda a,i:a[i], indices, arr)
都可以这样称呼
for i in index:
print (multiget(elements, *i))
编辑:
使用 reduce 似乎是三种方法中最快的,至少对于小型数组而言。我也觉得它看起来最干净
$ python -m timeit -s "def multiget_rec(arr, *indices):" \
-s " if len(indices)==0: return arr" \
-s " return multiget_rec(arr[indices[0]], *indices[1:])" \
-- "d = [[[3]]]" \
"multiget_rec(d, 0,0,0)"
500000 loops, best of 5: 941 nsec per loop
$ python -m timeit -s "def multiget_proc(arr, *indices):" \
-s " while len(indices)>0:" \
-s " i, *indices = indices" \
-s " return arr" \
-s "d = [[[3]]]" \
-- "multiget_proc(d, 0,0,0)"
500000 loops, best of 5: 529 nsec per loop
$ python -m timeit -s "from functools import reduce" \
-s "def multiget_reduce(arr, *indices):" \
-s " return reduce(lambda a,i:a[i], indices, arr)" \
-s "d = [[[3]]]" \
-- "multiget_reduce(d, 0,0,0)"
1000000 loops, best of 5: 384 nsec per loop
我知道这个问题是 6 年前的,但是 我的解决方案可能仍然有用。 (或不)
解法:
the_func = lambda func, index1, index2: func[index1][index2]
func = [[1,2,3,4],[5,6,7,8]]
index = [(1, 1), (0, 1)] # [6, 2]
print(the_func(func, *index[0]))