Mesut GUNES
Mesut GUNES

Reputation: 7401

Python how to create new lists from a list containing multiple lists depending on indexes

I have a list that stores lists with 5 elements. I want to create 5 new lists that store elements of each indexes. I have the following code but it seems not smart way.

>>> stats
[['1', '0', '36', '36', '3'], ['10', '0', '41', '77', '5'], ['1', '0', '631', '631', '63'], ['1', '0', '98', '98', '9'], ['9', '0', '52', '81', '6'], ['2', '0', '111', '167', '13'], ['1', '0', '98', '98', '9'], ['1', '0', '92', '92', '9'], ['2', '0', '241', '287', '26'], ['1', '0', '210', '210', '21'], ['2', '0', '336', '358', '34'], ['2', '0', '49', '57', '5'], ['5', '0', '52', '148', '7'], ['2', '0', '46', '76', '6'], ['3', '0', '33', '50', '4'], ['7', '0', '47', '70', '6'], ['1', '0', '94', '94', '9'], ['1', '0', '65', '65', '6'], ['1', '0', '66', '66', '6'], ['1', '0', '429', '429', '42'], ['1', '0', '337', '337', '33'], ['12', '0', '49', '126', '6'], ['1', '0', '47', '47', '4'], ['1', '0', '63', '63', '6'], ['1', '0', '79', '79', '7'], ['2', '0', '96', '100', '9'], ['1', '0', '36', '36', '3'], ['1', '0', '69', '69', '6'], ['6', '0', '44', '67', '5'], ['3', '0', '269', '385', '31'], ['2', '0', '78', '115', '9'], ['2', '0', '49', '52', '5'], ['3', '0', '26', '134', '9'], ['2', '0', '255', '561', '40'], ['1', '0', '75', '75', '7'], ['1', '0', '59', '59', '5'], ['2', '0', '59', '64', '6'], ['1', '0', '86', '86', '8'], ['1', '0', '63', '63', '6'], ['2', '0', '79', '100', '8'], ['4', '0', '825', '888', '86'], ['1', '0', '82', '82', '8'], ['3', '0', '65', '94', '7'], ['1', '0', '88', '88', '8'], ['1', '0', '344', '344', '34'], ['1', '0', '286', '286', '28'], ['1', '0', '73', '73', '7'], ['3', '0', '42', '69', '5'], ['1', '0', '151', '151', '15'], ['1', '0', '286', '286', '28'], ['2', '0', '47', '59', '5'], ['9', '0', '15', '41', '2'], ['2', '0', '343', '355', '34'], ['1', '0', '305', '305', '30'], ['1', '0', '238', '238', '23'], ['2', '0', '974', '2101', '153'], ['2', '0', '138', '142', '14'], ['7', '0', '45', '70', '5'], ['1', '0', '39', '39', '3']]
>>>
>>> num_requests,num_failures,min_response_time,max_response_time,avg_response_time = [], [], [], [], []
>>>
>>> for l in stats:
...  num_requests.append(l[0])
...  num_failures.append(l[1])
...  min_response_time.append(l[2])
...  max_response_time.append(l[3])
...  avg_response_time.append(l[4])
...
>>> num_requests
['1', '10', '1', '1', '9', '2', '1', '1', '2', '1', '2', '2', '5', '2', '3', '7', '1', '1', '1', '1', '1', '12', '1', '1', '1', '2', '1', '1', '6', '3', '2', '2', '3', '2', '1', '1', '2', '1', '1', '2', '4', '1', '3', '1', '1', '1', '1', '3', '1', '1', '2', '9', '2', '1', '1', '2', '2', '7', '1']

It could be stored in one list which stores 5 sublist.

Upvotes: 1

Views: 50

Answers (1)

Mike Müller
Mike Müller

Reputation: 85442

Solution

Just use zip with *:

(num_requests, num_failures, min_response_time, max_response_time, 
 avg_response_time) = zip(*stats)

This gives you tuples. Convert to lists if you need lists:

(num_requests, num_failures, min_response_time, max_response_time, 
 avg_response_time) = (list(x) for x in zip(*stats))

Details

A shorter example:

>>> data = [[1, 2, 3], [10, 20, 30], [100, 200, 300]]
>>> a, b, c = zip(*data)
>>> a
(1, 10, 100)
>>> b
(2, 20, 200)
>>> c
(3, 30, 300)

This is equivalent to:

a, b, c = zip(data[0], data[1], data[2])

but works for any number of sublists.

The left side uses tuple unpacking. For example, this:

x, y, z = (10, 20, 30)

assigns 10 to x, 20 to y, and 30 to z.

Performance

Measure how fast it is.

Version with append:

%%timeit
num_requests,num_failures,min_response_time,max_response_time,avg_response_time = [], [], [], [], []

for l in stats:
    num_requests.append(l[0])
    num_failures.append(l[1])
    min_response_time.append(l[2])
    max_response_time.append(l[3])
    avg_response_time.append(l[4])

10000 loops, best of 3: 51 µs per loop

Version with zip:

%%timeit
(num_requests, num_failures, min_response_time, max_response_time, 
     avg_response_time) = zip(*stats)

100000 loops, best of 3: 8.58 µs per loop

It is about five times faster.

It takes a bit longer when you convert the tuples to lists:

%%timeit
(num_requests, num_failures, min_response_time, max_response_time, 
 avg_response_time) = (list(x) for x in zip(*stats))

100000 loops, best of 3: 13.3 µs per loop

Still, about four times faster.

Upvotes: 3

Related Questions