2

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.

Robert Seifert
  • 25,078
  • 11
  • 68
  • 113
  • 4
    [Use `extend`](http://stackoverflow.com/questions/252703/python-append-vs-extend) like this `output = ["XYZ"]; output.extend(pointArray)` – Bhargav Rao Sep 03 '15 at 14:38
  • @BhargavRao, that would limit me to put something at the end of the list, wait I edit my question – Robert Seifert Sep 03 '15 at 14:42
  • 1
    Why not `output = ['ABC']+pointArray+['XYZ']` – Bhargav Rao Sep 03 '15 at 14:47
  • @BhargavRao because it is just a different way to achieve what I already have. The question was, if there is a possibilty to achieve it also with something similar to `*pointArray` which [obviously becomes included with the next version of python](http://stackoverflow.com/a/32378832/2605073). – Robert Seifert Sep 03 '15 at 14:53
  • @thewaywewalk Why, exactly, do you want to do it that way? I understand what you want to do, but I am not clear why it is so important that you do it that way. It won't make any performance difference, and it doesn't make the code any clearer (quite the opposite, in my opinion). So I don't quite understand what you are trying to achieve. – TheBlackCat Sep 03 '15 at 18:30
  • @TheBlackCat I get generated code by an application, it contains one single list which is sometimes 500 lines long. So imagine `'ABC'` and `'XYZ'` are 100 lines of code each and contain 100 nested list elements. The 300 list elements inbetween I want to generate separately and include it in the big list without touching the rest (I could, but as I need to do it more often, it would be easier if I needn't). Coming from Matlab I would have done it with a syntax similar as requested and for my case it was the obvious choice. I was just curios if it was possible, because I'm used to this syntax. – Robert Seifert Sep 03 '15 at 18:43
  • @TheBlackCat And also it was just an example, In Matlab there are a lot more cases where you can use this syntax and I wonder how versatile it becomes in the context of python when it gets released with the next version. And it is not "important" for me - as I said it was out of curiosity. I'm very new to Python and don't want to miss elementary functions ;) – Robert Seifert Sep 03 '15 at 18:46
  • @thewaywewalk I am familiar with MATLAB. One thing to keep in mind is that MATLAB is MATLAB and Python is Python, and trying to make one of them conform to the way the other does things usually results in ugly, poorly-performing code. Python hasn't supported this syntax up until now because it hasn't really been necessary. Python's syntax makes doing this sort of thing using concatenation considerably cleaner than MATLAB does, and makes doing it with slices and concatenation much cleaner. So this is one of many cases of trying to make Python work like MATLAB will serve you poorly. – TheBlackCat Sep 03 '15 at 19:13
  • @TheBlackCat - the answer "This functionality is not available in Python, because ..." would have been a valid, acceptable answer ;) Even "You can't!" - that was all I was requesting. But thanks for your opinion! – Robert Seifert Sep 04 '15 at 07:13

3 Answers3

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

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']]
alecxe
  • 462,703
  • 120
  • 1,088
  • 1,195
0
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']
Cody Bouche
  • 945
  • 5
  • 10