Bezdepbonusu7Программирование: статьи и ответы

Вопрос

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

Автор вопроса: michaelpriОтветов: 7

У меня есть список, назначенный переменной 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

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

  • Это должно быть правилом. Сколько "вложенных" мы говорим? 04.01.2015
  • Так это только ваш список? Нельзя изменить с помощью других вложенных списков? 04.01.2015
  • Вы хотите, чтобы это работало с вложенными списками, которые могут содержать строки, или списки содержат только числа? PM 2Ring 04.01.2015
  • Можете ли вы перечислить 11 списков, найденных во входных данных? thefourtheye 04.01.2015
  • @michaelpri Тогда ваш вопрос немного вводит в заблуждение, найдите длину всех вложенных списков? thefourtheye 04.01.2015
  • Вот хорошая функция для выравнивания произвольных вложенных списков: stackoverflow.com/a/2158532/4014959 . Используйте это, чтобы сгладить свой вложенный список, тогда вам просто нужно получить len() сглаженного списка. PM 2Ring 04.01.2015

pythonlistnested-lists

Ответы

Ответ 1 · рейтинг 19 · stonesam92

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

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

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

Ответ 2 · рейтинг 6 · Jean-François Fabre

взломать решение, кто-то должен был опубликовать его. Преобразуйте список в строку (оставьте тяжелый подъем/рекурсию оператору __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

Ответ 3 · рейтинг 6 · Anzel

В качестве альтернативы вы можете использовать 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 для устаревшего компилятора.ast функция сглаживания

Ответ 4 · рейтинг 2 · Jobs

По сути, вы ищете способ вычислить количество листьев в дереве.

 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 подсчитывает листья в дереве, рекурсивно вычисляя branch_counts ветвей, а затем суммируя эти результаты. В базовом случае дерево представляет собой лист, то есть дерево с 1 листом. Количество листьев отличается от длины дерева, то есть количества его ветвей.

Ответ 5 · рейтинг 2 · nbro

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

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))

Ответ 6 · ProgrammingIsAwsome

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

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 · nagordon

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

def listlength(mylist, k=0, indent=''):
    for l1 in mylist:
        if isinstance(l1, list):
            k = listlength(l1, k, indent+'  ')
        else:
            print(indent+str(l1))
            k+=1
    return k

a = [[1,2,3],[3,5,[2,3]], [[3,2],[5,[4]]]]
listlength(a)
# 11

и на всякий случай

a = []
x = listlength(a)
print('length={}'.format(x))
# length=0


a = [1,2,3]
x = listlength(a)
print('length={}'.format(x))
#1
#2
#3
#length=3


a = [[1,2,3]]
x = listlength(a)
print('length={}'.format(x))
#  1
#  2
#  3
#length=3


a = [[1,2,3],[1,2,3]]
x = listlength(a)
print('length={}'.format(x))
#  1
#  2
#  3
#  1
#  2
#  3
#length=6

a = [1,2,3, [1,2,3],[1,2,3]]
x = listlength(a)
print('length={}'.format(x))
#1
#2
#3
#  1
#  2
#  3
#  1
#  2
#  3
#length=9


a = [1,2,3, [1,2,3,[1,2,3]]]
x = listlength(a)
print('length={}'.format(x))
#1
#2
#3
#  1
#  2
#  3
#    1
#    2
#    3
#length=9


a = [ [1,2,3], [1,[1,2],3] ]
x = listlength(a)
print('length={}'.format(x))
#  1
#  2
#  3
#  1
#    1
#    2
#  3
#length=7

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы