将嵌套列表中的每个元素乘以一个常数

3
我可以帮您翻译,以下是翻译结果:

我一直在阅读类似的帖子,例如这里这里这里等等,但我仍然无法解决我的问题。我有一个像这样的列表:

 my_list = [[[0, 3], [0, 0]], [[77, 94], [76, 94], [77, 93], [76, 93], [76, 90], [77, 84], [76, 88]], [[25, 31], [10, 0]]]

我想要将每个整数乘以-1。我尝试了不同的方法,并得到了不同的错误,但这是我认为最合适的代码:

-1 * 整数

for p in range(len(my_list):
    for q in range(len(mylist[p])):
        my_new_list = [[i,j] * -1 for [i,j] in my_list[p][q]]

这一个甚至都无法工作!我最终想要的是像这样的东西:「最初的回答」。
my_new_list = [[[0, -3], [0, 0]], [[-77, -94], [-76, -94], [-77, -93], [-76, -93], [-76, -90], [-77, -84], [-76, -88]], [[-25, -31], [-10, 0]]]

能否有人帮我一下?

最初的回答:

3个回答

6
你面临的问题是,你最内层的循环创建了一个新的子列表,但没有将其适当地重新赋值(无论是给一个新列表还是给my_list)。每次都会重写上一次迭代的结果。
你需要使用三个循环的列表推导式,分别用于每个嵌套级别。
my_new_list = [[[z * -1 for z in y] for y in x] for x in my_list]

如果你能确保你的最内层列表总是成对出现,那么你可以根据@ShadowRanger的建议简化代码并使用两个循环的嵌套列表推导式。

my_new_list = [[[-a, -b] for a, b in x] for x in my_list]

这相当于执行:
import copy 

my_new_list = copy.deepcopy(my_list)
for x in my_new_list:
    for y in x:
        for i, z in enumerate(y): 
            y[i] = z * -1   # notice the assignment back to the sublist

1
鉴于最内层的list似乎总是成对出现,而不是任意长度,为了简化/加快速度,将其简化为:[[[-a, -b] for a, b in x] for x in my_list]可能是可取的,这样可以在一个list字面量中内联相同的工作,从而节省最内层的list推导。请注意,对于普通数字,-a只是拼写a * -1的一种更短/更快的方式,所以我选择了一元减号来简洁表达。 - ShadowRanger
@ShadowRanger 谢谢你的建议,这是一个对于配对操作很有用的优化技巧。 - cs95

2

要对任意深度的列表进行操作,您可以使用以下递归函数:

Original Answer翻译成"最初的回答"

def negate(list_or_int):
    if isinstance(list_or_int, list):
        # It's a list, so call negate on every element
        return [negate(i) for i in list_or_int]

    # It's an int, so just return the negative
    return -list_or_int

my_new_list = negate(my_list)

1
通过递归生成器可以实现更高效和优雅的解决方案:
def kprod(k,itr):
    for x in itr:
        yield k*x if isinstance(x, (int, float)) else tuple(kprod(k,x))

如果需要,可以用list替换tuple,但请记住,tuple稍微快一些。

该函数适用于任何深度和类型的嵌套可迭代对象,并返回一个生成器,因此当您想显示其内容时,必须通过应用tuplelist来展开它:

>>> my_list = [[[0, 3], [0, 0]], [[77, 94], [76, 94], [77, 93], [76, 93], [76, 90], [77, 84], [76, 88]], [[25, 31], [10, 0]]]
>>> tuple(kprod(-1,my_list))
(((0, -3), (0, 0)), ((-77, -94), (-76, -94), (-77, -93), (-76, -93), (-76, -90), (-77, -84), (-76, -88)), ((-25, -31), (-10, 0)))

>>> tuple(kprod(2,[3]))
(6,)

>>> tuple(kprod(2,[4,(5,(-1,0)),6]))
(8, (10, (-2, 0)), 12)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接