【问题标题】:Python Modify List of Lists [duplicate]Python修改列表列表[重复]
【发布时间】:2016-10-26 05:47:28
【问题描述】:

给定以下列表:

iters=[['EY11', 'EY12', 'EY13', 'EY14'],
       ['EY21', 'EY22', 'EY23', 'EY24'],
       ['PY11', 'PY12', 'PY13', 'PY14'],
       ['PY21', 'PY22', 'PY23', 'PY24']]

我想修改此列表以转置这些值(因为缺少更好的描述),如下所示:

iters=[['EY11', 'EY21', 'PY11', 'PY21'],
       ['EY12', 'EY22', 'PY12', 'PY22'],
       ['EY13', 'EY23', 'PY13', 'PY23'],
       ['EY14', 'EY24', 'PY14', 'PY24']]

我可以一次只使用一个子列表,如下所示:

[i[0] for i in iters]

但现在我只需要知道如何遍历每个子列表并自动制作新的列表列表(另外,我无法预测我的实际数据中会有多少子列表,所以我希望避免硬编码 i[0] 中当前子列表的数量。

提前致谢!

【问题讨论】:

    标签: python list python-3.x transpose


    【解决方案1】:

    你的意思是这样的:

    iters=[['EY11', 'EY12', 'EY13', 'EY14'],
           ['EY21', 'EY22', 'EY23', 'EY24'],
           ['PY11', 'PY12', 'PY13', 'PY14'],
           ['PY21', 'PY22', 'PY23', 'PY24']]
    
    
    def iterating(iters):
        if len(iters) > 0:
            range_len = len(iters[0]) 
            ret = []
            for idx in range(0,range_len):
                ret.append([i[idx] for i in iters])
            return ret
        return None
    
    if __name__ == '__main__':
        print iterating(iters)
    

    将输出到:

    [['EY11', 'EY21', 'PY11', 'PY21'], ['EY12', 'EY22', 'PY12', 'PY22'], ['EY13', 'EY23', 'PY13', 'PY23'], ['EY14', 'EY24', 'PY14', 'PY24']]
    

    该函数不是固定大小,但 id 确实假设列表中的所有列表大小相同。

    【讨论】:

      【解决方案2】:

      最简洁的解决方案是使用 the zip function 和星号解包:

      newiters = list(zip(*iters))  # Wrapping in list not needed on Python 2
      

      这几乎可以得到你想要的,但不完全是,因为它将是listtuples;如果没问题,你就完成了,如果没有,你只需调整它以转换为lists:

      newiters = list(map(list, zip(*iters)))  # Wrapping in list not needed on Python 2
      

      之所以可行,是因为星形解包使您将iters 的每个元素作为顺序位置参数传递给zip,例如:

      zip(['EY11', 'EY12', 'EY13', 'EY14'],
          ['EY21', 'EY22', 'EY23', 'EY24'],
          ['PY11', 'PY12', 'PY13', 'PY14'],
          ['PY21', 'PY22', 'PY23', 'PY24'])
      

      zip 的整个 schtick 正在从一组可迭代对象中匹配偏移量中生成新的 tuples 值,因此第一个 tuple 是每个参数的第一个元素 (('EY11', 'EY21', 'PY11', 'PY21')),第二个是每个参数的第二个元素 (('EY12', 'EY22', 'PY12', 'PY22')),等等。

      注意:这假设所有子lists 的长度相同。如果没有,您将丢失数据,因为zip 在最短的迭代用完时停止。如果您愿意,可以使用itertools.zip_longest 将较短的可迭代对象填充到最长可迭代对象的长度。

      【讨论】:

        【解决方案3】:

        这是一个使用列表理解的单行。

        transp = [[i[x] for i in iters] for x in range(0,4)]
        

        除了遍历索引之外,基本上你所做的。

        #Output
        ['EY11', 'EY21', 'PY11', 'PY21']
        ['EY12', 'EY22', 'PY12', 'PY22']
        ['EY13', 'EY23', 'PY13', 'PY23']
        ['EY14', 'EY24', 'PY14', 'PY24']
        

        【讨论】:

          【解决方案4】:

          如果这是您需要对阵列执行的唯一复杂操作,那么其他解决方案之一可能是最好的。但是,如果您不介意引入 numpy,那么有一个内置例程,称为 transpose

          import numpy as np
          iters_np = np.array(iters).transpose()
          print(iters_np)
          
          >>>[['EY11' 'EY21' 'PY11' 'PY21']
          >>> ['EY12' 'EY22' 'PY12' 'PY22']
          >>> ['EY13' 'EY23' 'PY13' 'PY23']
          >>> ['EY14' 'EY24' 'PY14' 'PY24']]
          

          【讨论】:

          • 这太棒了!我认为应该有一个操作来处​​理这些事情。谢谢!
          猜你喜欢
          • 2017-08-06
          • 1970-01-01
          • 2011-03-11
          • 2017-06-05
          • 2019-03-27
          • 2019-04-04
          • 1970-01-01
          相关资源
          最近更新 更多