2014-11-12 2 views
15

Функция принимает список и возвращает int в зависимости от того, сколько списков в списке не включает сам список. (Для простоты можно считать, все целое число или список.)Как найти количество вложенных списков в списке?

Например:

x=[1,2,[[[]]],[[]],3,4,[1,2,3,4,[[]] ] ] 

count_list(x) # would return 8 

Я думаю, используя рекурсию бы помочь, но я не уверен, как это осуществить, это что я до сих пор.

def count_list(a,count=None, i=None): 

    if count==None and i==None: 
     count=0 
     i=0 
    if i>len(a) 
     return(count) 
    if a[i]==list 
     i+=1 
     count+=1 
     return(count_list(a[i][i],count)) 
    else: 
     i+=1 
     return(count_list(a[i])) 
+6

Как насчет явно неправильный ответ? 'str (x) .count (" [") - 1' –

+1

, если в любом списке нет строк, это решение PROBABLY не хуже, чем рекурсия. Если в любом списке есть строки, у вас может быть строка, содержащая '' ['', которая все время сломает. –

+1

На линии 'def' должны быть одинаковые знаки равенства не двойные. –

ответ

17

Это, кажется, чтобы сделать работу:

def count_list(l): 
    count = 0 
    for e in l: 
     if isinstance(e, list): 
      count = count + 1 + count_list(e) 
    return count 
+3

Ну, с точки зрения человека, который не знает Python, я думаю, что ваш читатель более читабельен, хотя они, очевидно, делают то же самое. Для начинающих программистов, читабельность козырей, сохраняющих одну или две линии, на мой взгляд;) –

21

Вы можете сделать это с помощью функции рекурсии:

def count(l): 
    return sum(1+count(i) for i in l if isinstance(i,list)) 

Демо:

>>> x=[1,2,[[[]]],[[]],3,4,[1,2,3,4,[[]] ] ] 
>>> count(x) 
8 
+2

+1 для «питонического» способа решения этой проблемы – oopbase

3

Функциональное решение без циклов. Рекурсивно обрабатывает первый элемент списка и хвост списка. Добавьте один для каждого найденного пустого списка (то есть, как только мы закончим обработку некоторого списка, его хвост станет пустым, и мы добавим 1 к результату). И вычтите 1 для самого списка.

def number_of_lists(x): 
    f = lambda x: 0 if not isinstance(x,list) else (f(x[0]) + f(x[1:]) if len(x) else 1) 
    return f(x) - 1 

Результаты:

x=[1,2,[[[]]],[[]],3,4,[1,2,3,4,[[]] ] ] 
number_of_lists(x) 
>> 8 
5

Здесь вы сможете найти нерекурсивно решение:

  1. Во-первых, положить каждые элементы списка в стек
  2. Keep выскакивает элемент выключить стека до его исчерпания
  3. Если элемент является списком: a) посчитайте его, b) нажмите все элементы на дюйм ск

Код:

def count_list(lst): 
    """ Given a master list, count the number of sub-lists """ 
    stack = lst[:] 
    count = 0 
    while stack: 
     item = stack.pop() 
     if isinstance(item, list): 
      # If the item is a list, count it, and push back into the 
      # stack so we can process it later 
      count += 1 
      stack.extend(item) 
    return count 
3

Мне нравится этот хвост рекурсивной решение, хотя это не так много использования в Python ...

def count_lists(l, counter): 
    if (len(l) == 0): 
     return counter 
    else: 
     e = l.pop(0) 
     if (isinstance(e, list)): 
      l.extend(e) 
      return count_lists(l, 1 + counter) 
     else: 
      return count_lists(l, counter) 

x=[1,2,[[[]]],[[]],3,4,[1,2,3,4,[[]]]] 
print(count_lists(x, 0)) 
+0

Согласен. Bummer :( – ojy

+0

Я не очень разбираюсь в алгоритмах - есть ли причина, по которой вы делаете 'l.pop (0)' вместо 'l.pop()'? Если бы это сработало, то, MASSIVELY быстрее. –

+0

Да, есть разница между ними. 'Pop (0)' удаляет первый элемент из списка, в то время как 'pop()' удаляет последнее. Хорошая точка в производительности, алгоритм может быть изменен для использования pop (). – benji