Robert Seifert
Robert Seifert

Reputation: 25232

How to transform a list to a sequence of its comma-separated elements?

Imagine I have some coordinates given as a list of tuples:

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

and I need it to be a list as follows:

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

But I don't know in advance how many tuples there are in coordinates and I need to create the list dynamically.


First I used a loop to create the list without 'XYZ':

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

Then I appended 'XYZ' to the front and 'ABC' to the end:

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

Which gives me the desired output. But please consider this just as an example.

I'm not looking for alternative ways to append, extend, zip or chain arrays.


What I actually want to know: is there any syntax to create the list output also the following way:

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

but dynamically? So basically I'm looking for something like

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

which just seems to work for function arguments like

print(*pointArray)

To sum up: How can I transform a list to a sequence of its comma-separated elements? Is that even possible?


PS: In Matlab I was just used to use the colon {:} on cell arrays, to achieve exactly that.


Background

I'm recording Python skripts with an external application including the above mentioned lists. The recorded scripts sometimes contain over a hundred lines of codes and I need to shorten them. The easiest would be to just replace the looooong lists with a predefined-loop-created list and extend that array with the desired syntax.

Upvotes: 2

Views: 233

Answers (3)

You need to wait until Python 3.5 gets released:

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]

Until then, there is no really a general way:

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

However in limited scope you can use concatenation with +, and this would work for your example:

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

Unlike the * unpacking, or .extend, this only works for objects of same type:

>>> 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]

Upvotes: 3

Cody Bouche
Cody Bouche

Reputation: 955

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']

Upvotes: 0

alecxe
alecxe

Reputation: 473853

How about making a list comprehension involving zipping and chaining:

>>> 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']]

Upvotes: 1

Related Questions