【问题标题】:How to transform a list to a sequence of its comma-separated elements?如何将列表转换为其逗号分隔元素的序列?
【发布时间】:2015-09-03 22:55:51
【问题描述】:

假设我有一些坐标作为元组列表给出:

coordinates = [('0','0','0'),('1','1','1')] 

我需要它是一个如下列表:

['XYZ', ['CO', 'X', '0', 'Y', '0', 'Z', '0'], ['CO', 'X', '1', 'Y', '1', 'Z', '1'],'ABC']

但我事先不知道coordinates中有多少个元组,我需要动态创建列表。


首先我使用循环创建没有'XYZ'的列表:

pointArray = []
for ii in range(0, len(coordinates)):
    pointArray.append(
        [
            "CO",
            "X"           , coordinates[ii][0],
            "Y"           , coordinates[ii][1],
            "Z"           , coordinates[ii][2]
        ])

然后我在前面加上'XYZ',在最后加上'ABC'

output = pointArray
output [0:0] = ["XYZ"]
output.append("ABC")

这给了我想要的输出。 但这只是一个例子。

我不是在寻找附加、扩展、压缩或链式数组的替代方法。


我真正想知道的是:是否有任何语法可以通过以下方式创建列表output

output = ["XYZ", pointArray[0], pointArray[1], "ABC"]

但是动态的?所以基本上我正在寻找类似的东西

output = ["XYZ", *pointArray, "ABC"]

这似乎只适用于函数参数,如

print(*pointArray)

总结一下:如何将列表转换为逗号分隔元素的序列?这可能吗?


PS:在 Matlab 中,我只是习惯于在单元阵列上使用冒号 {:},来实现这一点。


背景

我正在使用包含上述列表的外部应用程序录制 Python 脚本。录制的脚本有时包含一百多行代码,我需要缩短它们。最简单的方法是将 looooong 列表替换为预定义循环创建的列表,并使用所需的语法扩展该数组。

【问题讨论】:

  • Use extend 喜欢这个output = ["XYZ"]; output.extend(pointArray)
  • @BhargavRao,这会限制我把一些东西放在列表的末尾,等我编辑我的问题
  • 为什么不output = ['ABC']+pointArray+['XYZ']
  • @BhargavRao 因为这只是实现我已经拥有的东西的另一种方式。问题是,是否有可能通过类似于*pointArray which obviously becomes included with the next version of python 的方式来实现它。
  • @thewaywewalk 为什么,确切地说,你想那样做?我理解你想做什么,但我不清楚为什么你这样做如此重要。它不会产生任何性能差异,也不会使代码更清晰(在我看来恰恰相反)。所以我不太明白你想要达到什么目的。

标签: python list python-3.x


【解决方案1】:

您需要等到 Python 3.5 发布:

Python 3.5.0a4+ (default:a3f2b171b765, May 19 2015, 16:14:41) 
[GCC 4.9.2] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> pointArray = [1, 2, 3]
>>> output = ["XYZ", *pointArray]
>>> output
['XYZ', 1, 2, 3]

在那之前,还没有真正通用的方法:

Python 3.4.3 (default, Mar 26 2015, 22:03:40) 
[GCC 4.9.2] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> pointArray = [1, 2, 3]
>>> output = ["XYZ", *pointArray]
  File "<stdin>", line 1
SyntaxError: can use starred expression only as assignment target

但是在有限的范围内,您可以使用与+ 的连接,这适用于您的示例:

>>> pointArray = [1, 2, 3]
>>> output = ["XYZ"] + pointArray
>>> output
['XYZ', 1, 2, 3]

* 解包或.extend 不同,这仅适用于相同类型的对象:

>>> pointArray = (1, 2, 3)
>>> output = ["XYZ"] + pointArray
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: can only concatenate list (not "tuple") to list
>>> output = ["XYZ"] + list(pointArray)
>>> output
['XYZ', 1, 2, 3]

【讨论】:

  • 这似乎是答案,因为我得出的结论是,所需的功能在 Python 3.4 之前不存在;)
  • @thewaywewalk 在您的情况下,您可以使用+ 在中间有一个列表,但将来您预期的* 将成为规则,因为它更通用。
【解决方案2】:

如何进行涉及zippingchaining 的列表理解:

>>> from itertools import chain, izip
>>>
>>> coordinates = [('0','0','0'),('1','1','1')] 
>>> axis = ['X', 'Y', 'Z']
>>> ['XYZ'] + [['CO'] + list(chain(*izip(axis, item))) for item in coordinates]
['XYZ', ['CO', 'X', '0', 'Y', '0', 'Z', '0'], ['CO', 'X', '1', 'Y', '1', 'Z', '1']]

【讨论】:

    【解决方案3】:
    import itertools
    
    cmap = 'XYZABC'
    coordinates = [('0','0','0'),('1','1','1')] 
    
    result = [cmap[:3]] + [list(itertools.chain(*[('CO', cmap[i], x) if i == 0 else (cmap[i], x) for i, x in enumerate(coordinate)])) for coordinate in coordinates] + [cmap[3:]]
    #['XYZ', ['CO', 'X', '0', 'Y', '0', 'Z', '0'], ['CO', 'X', '1', 'Y', '1', 'Z', '1'],'ABC']
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-06-04
      • 1970-01-01
      • 2016-10-24
      • 1970-01-01
      • 1970-01-01
      • 2020-04-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多