59

I want to iterate through list of list.
I want to iterate through irregularly nested lists inside list also.
Can anyone let me know how can I do that?

x = [u'sam', [['Test', [['one', [], []]], [(u'file.txt', ['id', 1, 0])]], ['Test2', [], [(u'file2.txt', ['id', 1, 2])]]], []]
3
  • 1
    Is there any system in the nesting of your list? What's the practical context of your iteration task, i.e. what are you doing with the elements in the list? Knowing this would help in providing tailored answers. Commented Jun 14, 2011 at 7:45
  • actually i just want to nest it Commented Jun 14, 2011 at 7:51
  • 3
    possible duplicate of Flatten (an irregular) list of lists in Python Commented Jun 14, 2011 at 7:53

11 Answers 11

65

This traverse generator function can be used to iterate over all the values:

def traverse(o, tree_types=(list, tuple)):
    if isinstance(o, tree_types):
        for value in o:
            for subvalue in traverse(value, tree_types):
                yield subvalue
    else:
        yield o

data = [(1,1,(1,1,(1,"1"))),(1,1,1),(1,),1,(1,(1,("1",)))]
print list(traverse(data))
# prints [1, 1, 1, 1, 1, '1', 1, 1, 1, 1, 1, 1, 1, '1']

for value in traverse(data):
    print repr(value)
# prints
# 1
# 1
# 1
# 1
# 1
# '1'
# 1
# 1
# 1
# 1
# 1
# 1
# 1
# '1'
Sign up to request clarification or add additional context in comments.

4 Comments

there is missing tree_types parameter in fourth line.
@Liso that parameter is optional, and given by default if left out
@nmz787 if you use non default parameter on top level then it will be forgotten on lower levels. Try to use list(traverse([1,2,3,set([4,5,6])],tree_types=(list,set))) with and without explicit calling tree_types in fourth line.
Why is the nested "for" required? When printing the leaves I found a single "for" works, but with "yield" it does not.
49

So wait, this is just a list-within-a-list?

The easiest way is probably just to use nested for loops:

>>> a = [[1, 3, 4], [2, 4, 4], [3, 4, 5]]
>>> a
[[1, 3, 4], [2, 4, 4], [3, 4, 5]]
>>> for list in a:
...     for number in list:
...         print number
...
1
3
4
2
4
4
3
4
5

Or is it something more complicated than that? Arbitrary nesting or something? Let us know if there's something else as well.

Also, for performance reasons, you might want to look at using list comprehensions to do this:

http://docs.python.org/tutorial/datastructures.html#nested-list-comprehensions

3 Comments

what if inner lists will be more?
@sam Same pattern applies. Example: 'a = [[[1, 2, 3], [4, 5, 6], [7, 8, 9]], [[10, 11, 12], [13, 14, 15], [16, 17, 18]], [[19, 20, 21], [22, 23, 24], [25, 26, 27]]] for list in a: for list in list: for number in list: print (number)'
The problem with this technique is that it doesn't allow for arbitrarily deep nests. At the time of writing the script you specify how deep each list should be, and that's that.
22

This can also be achieved with itertools.chain.from_iterable which will flatten the consecutive iterables:

import itertools
for item in itertools.chain.from_iterable(iterables):
    # do something with item    

1 Comment

it's itertools.chain.from_iterable actually
5

if you don't want recursion you could try:

x = [u'sam', [['Test', [['one', [], []]], [(u'file.txt', ['id', 1, 0])]], ['Test2', [], [(u'file2.txt', ['id', 1, 2])]]], []]
layer1=x
layer2=[]
while True:
    for i in layer1:
        if isinstance(i,list):
            for j in i:
                layer2.append(j)
        else:
            print i
    layer1[:]=layer2
    layer2=[]
    if len(layer1)==0:
        break

which gives:

sam
Test
Test2
(u'file.txt', ['id', 1, 0])
(u'file2.txt', ['id', 1, 2])
one

(note that it didn't look into the tuples for lists because the tuples aren't lists. You can add tuple to the "isinstance" method if you want to fix this)

Comments

4

It sounds like you need to use recursion. Make a function to iterate through a list, and if it hits an item that is also a list, call itself to iterate on the member. Here's a link to something similar:

http://www.saltycrane.com/blog/2008/08/python-recursion-example-navigate-tree-data/

1 Comment

If your list has arbitrary complexity, then you either have to use recursion, or simulate recursion by keeping a stack. You use the stack to push your "context" so that when you are done iterating your sub-list you can pop the stack to remember where you were. This works to an arbitrary depth without recursion, but it's more trouble than it's worth, and is essentially the same thing.
4

If you wonder to get all values in the same list you can use the following code:

text = [u'sam', [['Test', [['one', [], []]], [(u'file.txt', ['id', 1, 0])]], ['Test2', [], [(u'file2.txt', ['id', 1, 2])]]], []]

def get_values(lVals):
    res = []
    for val in lVals:
        if type(val) not in [list, set, tuple]:
            res.append(val)
        else:
            res.extend(get_values(val))
    return res

get_values(text)

2 Comments

Please note this is probably not optimal for just iterating the list, because a new list holding all of the elements is created. That is why I like the answer with a generator more.
@Jacek Konieczny - sure you are right, i have posted this solution for those who are not familiar with generators.
4
x = [u'sam', [['Test', [['one', [], []]], [(u'file.txt', ['id', 1, 0])]], ['Test2', [], [(u'file2.txt', ['id', 1, 2])]]], []]
output = []

def lister(l):
    for item in l:
        if type(item) in [list, tuple, set]:
            lister(item)
        else:
            output.append(item)

lister(x)

Comments

4

Create a method to recursively iterate through nested lists. If the current element is an instance of list, then call the same method again. If not, print the current element. Here's an example:

data = [1,2,3,[4,[5,6,7,[8,9]]]]

def print_list(the_list):

    for each_item in the_list:
        if isinstance(each_item, list):
            print_list(each_item)
        else:
            print(each_item)

print_list(data)

Comments

2

two nested for loops?

 for a in x:
     print "--------------"
     for b in a:
             print b

It would help if you gave an example of what you want to do with the lists

1 Comment

Exactly what I wanted to ask. What if there are more than 2 levels of nested list. This answer is a bound to many questions.
1
# house list of lists
house = [["hallway", 11.25], ["kitchen", 18.0], ["living room", 20.0], 
         ["bedroom", 10.75], ["bathroom", 9.50]]
         
for key, y in house :
    print('The ' + key + ' is ' + str(y) + ' sqm ')

1 Comment

Your answer is valid in the context of your example¹, and it is quite simple which is good. Unfortunately, it won't work in the context of the question. 1 – And in any context where you know your iterable only contains 2-elements iterables.
-1
mylist12 = [1,2,[3,4],[5,6,7],8]

print(dir(mylist12)) # iterable


for i in mylist12:
    if (isinstance(i,list)):
        for j in i:
            print(j)
    else:
            print(i)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.