Say I have a list [1, [2, 1], 1, [3, [1, 3]], [4, [1], 5], [1], 1, [[1]]]
And I want to count the number of 1's in the list. How do i do that with .count ?? Is there anyway to remove [] like enumerate(seq) which removes () then count the number of 1's in the list?
            Asked
            
        
        
            Active
            
        
            Viewed 96 times
        
    1
            
            
         
    
    
        user3398505
        
- 607
- 1
- 7
- 13
- 
                    A) recursion B) flatten – Karoly Horvath Mar 14 '14 at 11:36
- 
                    C) use regex :) `len(re.findall(r'\b1\b', str(xs)))` – behzad.nouri Mar 14 '14 at 12:03
2 Answers
4
            
            
        This might not be the coolest way, but it works:
l=[1, [2, 1], 1, [3, [1, 3]], [4, [1], 5], [1], 1, [[1]]]
>>> from compiler.ast import flatten
>>> flatten(l).count(1)
8
Here, as name suggests, flatten() converts the nested list into simple single level list. And counting the number of 1s from resulting list achieves the task.
 
    
    
        santosh-patil
        
- 1,540
- 1
- 15
- 29
- 
                    It wont work in python 3 though as the compiler module has been removed. – Reite Mar 14 '14 at 12:20
2
            You need a function to traverse an arbitrarily nested list. Then the counting is trivial. The traversing can be accomplished with a recursive generator:
def traverse(val):
    if isinstance(val, list):
        for v in val:
            for x in traverse(v):
                yield x 
    else:
        yield val
>>> list(traverse([1, [2, 1], 1, [3, [1, 3]], [4, [1], 5], [1], 1, [[1]]]))
[1, 2, 1, 1, 3, 1, 3, 4, 1, 5, 1, 1, 1]
This definition would be even nicer with the new yield from syntax in python 3.3, with it we could replace one of the loops:
def traverse(val):
    if isinstance(val, list):
        for v in val:
            yield from traverse(v)
    else:
        yield val
 
    
    
        Reite
        
- 1,677
- 10
- 12