There are two important one line idioms in Python that help make this "straightforward".
The first idiom, use zip(). From the Python documents:
The left-to-right evaluation order of the iterables is guaranteed. This makes possible an idiom for clustering a data series into n-length groups using zip(*[iter(s)]*n).
So applying to your example:
>>> num_str = '5,4,2,4,1,0,3,0,5,1,3,3,14,32,3,5'
>>> zip(*[iter(num_str.split(","))]*2)
[('5', '4'), ('2', '4'), ('1', '0'), ('3', '0'), ('5', '1'),
('3', '3'), ('14', '32'), ('3', '5')]
That produces tuples each of length 2.
If you want the length of the sub elements to be different:
>>> zip(*[iter(num_str.split(","))]*4)
[('5', '4', '2', '4'), ('1', '0', '3', '0'), ('5', '1', '3', '3'),
('14', '32', '3', '5')]
The second idiom is list comprehensions. If you want sub elements to be lists, wrap in a comprehension:
>>> [list(t) for t in zip(*[iter(num_str.split(","))]*4)]
[['5', '4', '2', '4'], ['1', '0', '3', '0'], ['5', '1', '3', '3'],
['14', '32', '3', '5']]
>>> [list(t) for t in zip(*[iter(num_str.split(","))]*2)]
[['5', '4'], ['2', '4'], ['1', '0'], ['3', '0'], ['5', '1'], ['3', '3'],
['14', '32'], ['3', '5']]
Any sub element groups that are not complete will be truncated by zip(). So if your string is not a multiple of 2, for example, you will loose the last element.
If you want to return sub elements that are not complete (ie, if your num_str
is not a multiple of the sub element's length) use a slice idiom:
>>> l=num_str.split(',')
>>> [l[i:i+2] for i in range(0,len(l),2)]
[['5', '4'], ['2', '4'], ['1', '0'], ['3', '0'], ['5', '1'],
['3', '3'], ['14', '32'], ['3', '5']]
>>> [l[i:i+7] for i in range(0,len(l),7)]
[['5', '4', '2', '4', '1', '0', '3'], ['0', '5', '1', '3', '3', '14', '32'],
['3', '5']]
If you want each element to be an int, you can apply that prior to the other transforms discussed here:
>>> nums=[int(x) for x in num_str.split(",")]
>>> zip(*[iter(nums)]*2)
# etc etc etc
As pointed out in the comments, with Python 2.4+, you can also replace the list comprehension with a Generator Expression by replacing the [ ]
with ( )
as in:
>>> nums=(int(x) for x in num_str.split(","))
>>> zip(nums,nums)
[(5, 4), (2, 4), (1, 0), (3, 0), (5, 1), (3, 3), (14, 32), (3, 5)]
# or map(list,zip(nums,nums)) for the list of lists version...
If your string is long, and you know that you only need 2 elements, this is more efficient.