动态编写多列列表

2024-06-16 11:39:52 发布

您现在位置:Python中文网/ 问答频道 /正文

嗨,我写了一个清单如下:

> l = [[10312, -13.069404602050781], [10313, -28.044403076171875],
>      [10314, -32.765602111816406], [10315, -47.353294372558594],
>      [10312, -63.069404602050781], [10313, -78.044403076171875],
>      [10314, -82.765602111816406], [10315, -97.353294372558594]]

从第3行可以看出,列表的第一项被重复,我试图实现的是,循环一达到maxCount,它就不会一直追加到列表的底部,而是追加到右侧。我最想得到的是:

 l = [[10312, -13.069404602050781, -63.069404602050781], 
      [10313, -28.044403076171875, -78.044403076171875],
      [10314, -32.765602111816406, -82.765602111816406], 
      [10315, -47.353294372558594, -97.353294372558594]]

有什么想法吗?你知道吗

我已经想出了一个解决方案,但我觉得有点有限,我现在使用的列表生成器列表,像这样

 table=[]
     for k in range(0, len(elementContainer):
         k = []
         table.append(k)

我想给你一个字典生成器,但无法让它工作,任何帮助或如果你有更好的解决方案。你知道吗


Tags: in列表forlen字典tablerange解决方案
1条回答
网友
1楼 · 发布于 2024-06-16 11:39:52

如果我没记错的话,这就行了:

l = [[10312, -13.069404602050781], [10313, -28.044403076171875],
     [10314, -32.765602111816406], [10315, -47.353294372558594],
     [10312, -63.069404602050781], [10313, -78.044403076171875],
     [10314, -82.765602111816406], [10315, -97.353294372558594]]

from pprint import pprint
d = {}

for i,(x,n) in enumerate(l):
    print i,x,n
    if x in d:
        l[d[x]].append(n)
        del l[i][:]
    else:
        d[x] = i

l = filter(None,l)

pprint (l)

是的。你知道吗

编辑

这里有一个更好的算法,因为不再需要指令l = filter(None,l)对列表进行过滤,所以转换已经就绪。你知道吗

这个指令l = filter(None,l)创建了一个新列表,也就是说在内存中的另一个地址创建了一个新对象:那么上面的代码就不能实现列表的就地转换了。
下面的一个执行这样的就地转换,因为它通过在处理前后打印列表l的标识(id est addresses)而成为证据。你知道吗

l = [[10312, -13.069404602050781],
     [10313, -28.044403076171875],
     [10314, -32.765602111816406],
     [10312, -63.069404602050781, -55.4444],
     [20666, -91, -92, -93, -94],
     [10315, -47.353294372558594],
     [10314, -82.765602111816406],
     [10315, -97.353294372558594],
     [10313, -78.044403076171875],
     [20666, -40.33, -94, -50.33, -91, -93]
     ]

from pprint import pprint
d = {}
to_del = []
print 'id(l) before : ',id(l)
pprint (l)

for i,subli in enumerate(l):
    if subli[0] in d:
        d[subli.pop(0)].extend(subli)
        to_del.insert(0,i)
    else:
        d[subli[0]] = subli

for i in to_del:
    del l[i]

print '\nid(l) after  : ',id(l)
pprint (l)
  • 注意,在前面的代码中,d的值是l的子列表的索引。
    现在在这个新代码中,d的值直接是l
    直接引用对象比通过列表中的索引间接引用对象更具python风格。

  • 列表to_del记录第一次循环后将被删除的子列表的索引。添加的每个索引都插入到to_del的开头(不是附加到它的后面),这样第二个循环(for i in to_del)将在列表l中逆向运行,这是根据索引删除列表元素时必须遵守的条件。

指令d[subli.pop(0)].extend(subli)似乎有点难以理解。你知道吗

操作从执行subli.pop(0)开始:此指令触发从子列表subli提取索引为0的元素并返回它。
然后d[subli.pop(0)]提供对象次li.pop(0)d作为键,同时此对象从子列表subli中删除。
因此,在这一点上,子列表subli已经缩短了它的第一个元素,就好像指令subli[:] = subli[1:]已经执行了一样参见底部的备注。你知道吗

接下来,在通过列表l的迭代期间在l中先前遇到的子列表d[subli.pop(0)]在该子列表被缩短之后被扩展为子列表subli中剩余的元素,也就是说,在子列表被缩短之前被索引1len(subli)-1的元素。但是,由于subli被缩短了,我们只写subli,而不是subli[1:]。你知道吗

而且有效!结果:

id(l) before :  18732936
[[10312, -13.069404602050781],
 [10313, -28.044403076171875],
 [10314, -32.765602111816406],
 [10312, -63.06940460205078, -55.4444],
 [20666, -91, -92, -93, -94],
 [10315, -47.353294372558594],
 [10314, -82.7656021118164],
 [10315, -97.3532943725586],
 [10313, -78.04440307617188],
 [20666, -40.33, -94, -50.33, -91, -93]]

id(l) after  :  18732936
[[10312, -13.069404602050781, -63.06940460205078, -55.4444],
 [10313, -28.044403076171875, -78.04440307617188],
 [10314, -32.765602111816406, -82.7656021118164],
 [20666, -91, -92, -93, -94, -40.33, -94, -50.33, -91, -93],
 [10315, -47.353294372558594, -97.3532943725586]]

是的。你知道吗

如果希望仅将非冗余元素添加到以前存在的子列表中,则必须:

for i,subli in enumerate(l):
    print 1,subli
    if subli[0] in d:
        precsubli = d[subli.pop(0)]
        precsubli.extend(el for el in subli
                         if el not in precsubli)
        to_del.insert(0,i)
    else:
        d[subli[0]] = subli

是的。你知道吗

重要提示

注意区别:

N = [10000,2,3,4]

initial_id = id(N)
print initial_id, N

N = N[1:]

print id(N), N
print '%d==%d : %s' %\
      (initial_id, id(N), initial_id==id(N) )

print '         '

A = ['HEY','b','c','d']

initial_id = id(A)
print initial_id, A

A[:] = A[1:]

print id(A), A
print '%d==%d : %s' %\
      (initial_id, id(A), initial_id==id(A) )

结果

18669480 [10000, 2, 3, 4]
11868480 [2, 3, 4]
18669480==11868480 : False
         
18731816 ['HEY', 'b', 'c', 'd']
18731816 ['b', 'c', 'd']
18731816==18731816 : True

这意味着A被就地修改,而N引用的对象却没有被修改:指令N[1:]在内存中某个位置构建了一个新对象,而不是N引用的对象的位置。你知道吗

相关问题 更多 >