14

I have a list like this:

[[(video1,4)], [(video2,5),(video3,8)], [(video1,5)], [(video5, 7), (video6,9)]...]

each item in this list may contain a single data pair, or a tuple, I want to change this list into

[(video1,4),(video2,5),(video3,8),(video1,5),(video5,7),(video6,9)...]

then do this:

for item in list:
    reqs = reqs + item[1]
    b.append(item[0])
c = set(b)

I don't know how to change the list structure, or how to do the same calculation based on the original list?

Marcin
  • 48,559
  • 18
  • 128
  • 201
manxing
  • 3,165
  • 12
  • 45
  • 56
  • Do you need the `...` in the example list? it would be a working example without it. – jamylak Apr 12 '12 at 15:41
  • 1
    What do you actually want to achieve in the end? A set `c` of `videoX` variables and the sum of the other numbers you've listed? – Shep Apr 12 '12 at 15:44
  • @jamylak no, .... means there're lots more similar data which I don't to list them all – manxing Apr 12 '12 at 15:46
  • @Shep yes, this list contains lots of data, not just the ones I listed here, but basically that's what I want to do – manxing Apr 12 '12 at 15:47
  • 1
    Does this answer your question? [How do I make a flat list out of a list of lists?](https://stackoverflow.com/questions/952914/how-do-i-make-a-flat-list-out-of-a-list-of-lists) – questionto42 Jul 08 '22 at 18:41

7 Answers7

15

There is a very simple way of doing this with list comprehensions. This example has been documented in the python documentation here

>>> # flatten a list using a listcomp with two 'for'
>>> vec = [[1,2,3], [4,5,6], [7,8,9]]
>>> [num for elem in vec for num in elem]
[1, 2, 3, 4, 5, 6, 7, 8, 9]

Here is the solution that you would want to implement. As per your example, this is the simplest solution

In [59]: your_list = [[('video1',4)], [('video2',5),('video3',8)], [('video1',5)], [('video5', 7), ('video6',9)]]

In [60]: improved_list = [num for elem in your_list for num in elem]

In [61]: improved_list
Out[61]: 
[('video1', 4),
 ('video2', 5),
 ('video3', 8),
 ('video1', 5),
 ('video5', 7),
 ('video6', 9)]
ronak
  • 1,770
  • 3
  • 20
  • 34
13

If this list is singly-nested (list of lists) you can do this, which I use a lot:

flat_list = sum(list_of_lists, [])

This works due to the fact that sum simply adds up the lists, and adding up lists works in python as expected :)

Note: This is inefficient and some say unreadable.

Reut Sharabani
  • 30,449
  • 6
  • 70
  • 88
11

To flatten one level, you can use itertools.chain.from_iterable():

flattened_list = itertools.chain.from_iterable(my_list)
Sven Marnach
  • 574,206
  • 118
  • 941
  • 841
10

If you just want to flatten the list, just use itertools.chain.from_iterable: http://docs.python.org/library/itertools.html#itertools.chain.from_iterable

Marcin
  • 48,559
  • 18
  • 128
  • 201
2

Here's another one (no libraries):

def plus(a,b): return a + b
reduce(plus, your_list)
rodion
  • 14,729
  • 3
  • 53
  • 55
1

Try this:

from itertools import chain 

c = set()
reqs = 0
for vid, number in chain(*your_list): 
    c.add(vid)
    reqs += number 

Also see related post Flattening a shallow list in Python.

There should be negligible performance increase from using chain.from_iterable(list) rather than chain(*list), but it's true that the former looks cleaner.

Community
  • 1
  • 1
Shep
  • 7,990
  • 8
  • 49
  • 71
-1

to extract all tuples from a data structure ...

def get_tups(y):
    z = []
    if y:
        for x in y:
            if isinstance(x, tuple):
                z.append(x)
            else:
                z.extend(get_tups(x))
    return z

maybe ...

Gwyn Howell
  • 5,365
  • 2
  • 31
  • 48
  • what happens if I call `get_tups([('foo',)])`? – Marcin Apr 12 '12 at 16:13
  • since the input contains 1 tuple, you will get a list containing the 1 tuple. in other words, the output will be the same as the input ;) – Gwyn Howell Apr 12 '12 at 16:18
  • And then what happens if I call it a second time? Here's a hint: http://ideone.com/zgMzq – Marcin Apr 12 '12 at 16:41
  • ahh. why is z not an empty list the second time it is called? – Gwyn Howell Apr 12 '12 at 16:50
  • Because you append a value to it in your code, and the expression `z=[]` is evaluated as part of the `def` statement. – Marcin Apr 12 '12 at 16:51
  • get_tups([('foo',)]) get_tups([('foo',)]) .. on line 2 i pass no variable for z. therefore i would expect it to assume [] – Gwyn Howell Apr 12 '12 at 16:53
  • It's your job to tell the computer what to do, not hope it makes assumptions. – Marcin Apr 12 '12 at 16:55
  • let me rephrase. i would expect it to default to [], since the parameter is a default parameter, and is not passed into the method. it seems to 'remember' the previous value of z. like its a global or something. i thought the scope of z was within the method itself. therefore, the second time it was called, it would re-initialize to []. sorry if i'm being dumb – Gwyn Howell Apr 12 '12 at 16:58
  • I've already explained why it happens: `z=[]` is evaluated as part of the `def` statement. Incidentally, your function also doesn't cope with circular input: http://ideone.com/YOaPS – Marcin Apr 12 '12 at 17:02
  • for completeness, i have fixed the code - http://ideone.com/o8PO6. thanks for your help @Marcin – Gwyn Howell Apr 13 '12 at 07:15
  • Awesome. You can edit your answer - it is definitely encouraged. – Marcin Apr 13 '12 at 08:23