7

I need to generate a list for scipy.optimize.minimize's boundry condition, it should look like this:

bonds = [(0., 0.99),(-30, 30),(-30, 30),(0., 30),(0., 30),(-0.99, 0.99),
        (0., 0.99),(-30, 30),(-30, 30),(0., 30),(0., 30),(-0.99, 0.99),
        (0., 0.99),(-30, 30),(-30, 30),(0., 30),(0., 30),(-0.99, 0.99),]

I'm wondering if there is any elegant way of doing it?

I tried:

bonds = [[(0., 0.99),(-30, 30),(-30, 30),(0., 30),(0., 30),(-0.99, 0.99)] for i in range(3)]

But this generates

[[(0.0, 0.99), (-30, 30), (-30, 30), (0.0, 30), (0.0, 30), (-0.99, 0.99)],
 [(0.0, 0.99), (-30, 30), (-30, 30), (0.0, 30), (0.0, 30), (-0.99, 0.99)],
 [(0.0, 0.99), (-30, 30), (-30, 30), (0.0, 30), (0.0, 30), (-0.99, 0.99)]]

How can I remove the inner [], to unravel the inner arrays into a single one? Or is there any other good way of doing it?

Lafexlos
  • 7,618
  • 5
  • 38
  • 53
ZK Zhao
  • 19,885
  • 47
  • 132
  • 206
  • 2
    Not necessarily what you may want, but a [reference link](http://stackoverflow.com/questions/952914/making-a-flat-list-out-of-list-of-lists-in-python) for ways to flatten a list of lists. – Reti43 Dec 28 '15 at 12:58
  • @Reti43, thanks, that's another way of thinking this problem. I just didn't think about `flat` at all. – ZK Zhao Dec 30 '15 at 01:35

3 Answers3

10

you can do:

bonds = [(0., 0.99),(-30, 30),(-30, 30),(0., 30),(0., 30),(-0.99, 0.99)] * 3
LinnTroll
  • 705
  • 4
  • 10
2

[i for sublist in bonds for i in sublist]

vesche
  • 1,842
  • 1
  • 13
  • 19
  • 4
    Please add some supporting text for this code snippet. Explain why it would solve the OP's problem. Help others to understand. – APC Dec 28 '15 at 08:22
1

Other way, using chain.from_iterable from itertools module:

>>> l = [(0.0, 0.99), (-30, 30), (-30, 30), (0.0, 30), (0.0, 30), (-0.99, 0.99)]
>>> bonds = list(itertools.chain.from_iterable(l*3))
>>> bonds
[0.0, 0.99, -30, 30, -30, 30, 0.0, 30, 0.0, 30, -0.99, 0.99, 0.0, 0.99, -30, 30, -30, 30, 0.0, 30, 0.0, 30, -0.99, 0.99, 0.0, 0.99, -30, 30, -30, 30, 0.0, 30, 0.0, 30, -0.99, 0.99] 

EDIT: Comparing the speed of some expression, I've tried the following:

$ python3 -mtimeit -s 'l = [(0., 0.99),(-30, 30),(-30, 30),(0., 30),(0., 30),(-0.99, 0.99)]' 'bonds=list(itertools.chain.from_iterable(l*3))'
1000000 loops, best of 3: 1.95 usec per loop
$ python3 -mtimeit -s 'l = [(0., 0.99),(-30, 30),(-30, 30),(0., 30),(0., 30),(-0.99, 0.99)]' 'bonds = l*3'
10000000 loops, best of 3: 0.147 usec per loop
$ python3 -mtimeit -s 'l = [(0., 0.99),(-30, 30),(-30, 30),(0., 30),(0., 30),(-0.99, 0.99)]' 'bonds=list(itertools.chain(l*3))'
1000000 loops, best of 3: 0.859 usec per loop

As one can notice, bonds = l*3 is the fastest among the above expressions.

Iron Fist
  • 10,739
  • 2
  • 18
  • 34