Как я могу получить общее количество элементов в моем произвольно вложенном списке списков?

У меня есть список, назначенный переменной my_list. Значение my_list равно [[1,2,3],[3,5,[2,3]], [[3,2],[5,[4]]]]. Мне нужно найти длину my_list, но len(my_list) возвращает только 3. Я хочу, чтобы она вернула 11. Есть ли какие-либо функции Python, которые вернут всю длину my_list вложенных списков и всех.

Пример:

Input
[[1,2,3],[3,5,[2,3]], [[3,2],[5,[4]]]]

Output
11

Я бы хотел, чтобы это работало не только для чисел, но и для строк.

Ответ 1

Эта функция подсчитывает длину списка, считая любой объект, отличный от списка, как длина 1, и рекурсирует на элементах списка, чтобы найти сплющенную длину, и будет работать с любой степенью вложенности до максимальной глубины стека интерпретаторов.

def recursive_len(item):
    if type(item) == list:
        return sum(recursive_len(subitem) for subitem in item)
    else:
        return 1

Примечание: в зависимости от того, как это будет использоваться, может быть лучше проверить, является ли элемент итерабельным, а не проверяет, имеет ли он тип list, чтобы правильно судить о размерах кортежей и т.д. проверка, если объект итерируется, будет иметь побочный эффект подсчета каждого символа в строке, а не указание длины строки 1, что может быть нежелательным.

Ответ 2

В качестве альтернативы вы можете использовать flatten с len:

from compiler.ast import flatten

my_list = [[1,2,3],[3,5,[2,3]], [[3,2],[5,[4]]]]

len(flatten(my_list))
11

PS. спасибо за указание @thefourtheye, обратите внимание:

Устаревший с версии 2.6: пакет компилятора был удален в Python 3.

Альтернативы можно найти здесь: замена Python 3 для устаревшей функции compiler.ast flatten

Ответ 3

Взломать решение, кто-то должен был опубликовать его. Преобразуйте список в строку (оставьте тяжелый подъем/рекурсию оператору __str__), затем посчитайте запятые, добавьте 1.

>>> my_list = [[1,2,3],[3,5,[2,3]], [[3,2],[5,[4]]]]
>>> str(my_list).count(",")+1
11

(работает для целых чисел и чисел с плавающей запятой, конечно, не работает со строками, потому что они могут содержать запятые)

РЕДАКТИРОВАТЬ: этот хак не учитывает пустые списки: мы должны удалить элементы []:

>>> my_list = [[1,2,3],[3,5,[2,3]], [[3,2],[5,[4],[]]]]  # added empty list at the end
>>> s = str(my_list)
>>> s.count(",")-s.count("[]")+1   # still 11

Ответ 4

Это альтернативное решение, которое может быть не столь впечатляющим, поскольку оно заполняет новый сплющенный список, который возвращается в конце:

def flatten_list(ls, flattened_list=[]):
    for elem in ls:
        if not isinstance(elem, list): 
            flattened_list.append(elem)
        else:
            flatten_list(elem, flattened_list)
    return flattened_list

flatten_list интуитивно выравнивает список, а затем вы можете рассчитать длину нового возвращенного сплющенного списка с помощью функции len():

len(flatten_list(my_list))

Ответ 5

В основном вы ищете способ вычисления количества листьев в дереве.

 def is_leaf(tree):
        return type(tree) != list

def count_leaves(tree):
    if is_leaf(tree):
        return 1
    else:
        branch_counts = [count_leaves(b) for b in tree]
        return sum(branch_counts)

Функция count_leaves подсчитывает листья в дереве путем рекурсивного вычисления ветвей ветвей ветвей, а затем суммирует эти результаты. Базовый корпус - это дерево, которое является деревом с 1 листом. Количество листьев отличается от длины дерева, а именно его ветвей.

Ответ 6

Вот моя реализация:

def nestedList(check):
    returnValue = 0
    for i in xrange(0, len(check)):
        if(isinstance(check[i], list)):
            returnValue += nestedList(check[i])
        else:
            returnValue += 1
    return returnValue

Ответ 7

Простой способ для tuple или list

Для tuple

from nltk import flatten
Obj = (0.4, ((0.1, (0.05, 0.07)), (0.18, 0.2)))
print(len(flatten(list(Obj))))

Для List

 Obj = [[1,2,3],[3,5,[2,3]], [[3,2],[5,[4]]]]
 print(len(flatten((Obj))))