Nano Hash - криптовалюты, майнинг, программирование

Вложенный список и count ()

Я хочу узнать, сколько раз x появляется во вложенном списке.

если список:

list = [1, 2, 1, 1, 4]
list.count(1)
>>3

Хорошо. Но если список такой:

list = [[1, 2, 3],[1, 1, 1]]

Как я могу узнать, сколько раз появляется 1? В этом случае 4.

29.04.2011


Ответы:


1

Вот еще один подход к сглаживанию вложенной последовательности. После того, как последовательность выровнена, можно легко проверить количество элементов.

def flatten(seq, container=None):
    if container is None:
        container = []

    for s in seq:
        try:
            iter(s)  # check if it's iterable
        except TypeError:
            container.append(s)
        else:
            flatten(s, container)

    return container


c = flatten([(1,2),(3,4),(5,[6,7,['a','b']]),['c','d',('e',['f','g','h'])]])
print(c)
print(c.count('g'))

d = flatten([[[1,(1,),((1,(1,))), [1,[1,[1,[1]]]], 1, [1, [1, (1,)]]]]])
print(d)
print(d.count(1))

Приведенный выше код печатает:

[1, 2, 3, 4, 5, 6, 7, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']
1
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
12
29.04.2011
  • В этом примере происходит сбой моего ядра. 10.02.2019
  • Это приводит к переполнению стека, потому что строка типа 'a' на самом деле является итерируемой. Это означает, что он будет продолжать вызывать рекурсию. 16.10.2020
  • хм, я немного смущен, я опубликовал этот код довольно давно (9 лет), и обычно я запускаю и тестирую свой код перед публикацией. Теперь, когда я проверяю оба с помощью python / 2.7 и python / 3.7, приведенный выше код дает сбой. Поэтому не уверен, что приведенный выше код дает сбой даже с интерпретатором python, в котором я запускал приведенный выше код (я не помню, какая это была версия), и если поведение iter изменилось между версиями или опубликованный мной код был неправильным с того дня Я написал, и ошибка осталась незамеченной. 17.10.2020

  • 2

    Модули itertools и collections получили именно то, что вам нужно (сгладьте вложенные списки с помощью itertools.chain и считайте с помощью collections.Counter

    import itertools, collections
    
    data = [[1,2,3],[1,1,1]]
    counter = collections.Counter(itertools.chain(*data))
    print counter[1]
    

    Используйте рекурсивную функцию сглаживания вместо itertools.chain для сглаживания вложенных списков произвольной глубины уровня

    import operator, collections
    
    def flatten(lst):
        return reduce(operator.iadd, (flatten(i) if isinstance(i, collections.Sequence) else [i] for i in lst))
    

    reduce с operator.iadd использовался вместо sum, так что развертка создается только один раз и обновляется на месте

    29.04.2011

    3

    Попробуй это:

    reduce(lambda x,y: x+y,list,[]).count(1)
    

    Обычно вы начинаете с пустого списка [] и добавляете к нему каждый элемент списка list. В этом случае элементы сами по себе являются списками, и вы получаете сплющенный список.

    PS: Только что проголосовали за аналогичный ответ в другом вопросе!

    PPS: Только что проголосовали за это решение!

    29.04.2011
  • Люди здесь произвольно понижают голосование. Проголосуйте за дрянные решения. Моя определенно нет. И нет упоминания о произвольном вложении, упомянутом и работает для случая OP. Не думай слишком много. 29.04.2011
  • Да, потому что вы отказываетесь думать еще дальше и лучше разобраться в более глубокой проблеме и в том, как найти более общее решение. 29.04.2011
  • .. так говорит человек, который говорит поиск в гугле. 29.04.2011
  • Отличный ответ. Кого волнует, что говорит @AndreasJung. Ответ соответствует вопросу. 07.02.2014

  • 4

    Если есть только один уровень вложенности, выравнивание может быть выполнено с помощью этого расширения списка:

    >>> L = [[1,2,3],[1,1,1]]
    >>> [ item for sublist in L for item in sublist ].count(1)
    4
    >>> 
    
    29.04.2011
  • просто и легко. 11.03.2021

  • 5

    На всякий случай: подсчитайте до любой произвольной глубины вложенности, обрабатывая кортежи, списки и аргументы:

    hits = lambda num, *n: ((1 if e == num else 0)
        for a in n
            for e in (hits(num, *a) if isinstance(a, (tuple, list)) else (a,)))
    
    lst = [[[1,(1,),((1,(1,))), [1,[1,[1,[1]]]], 1, [1, [1, (1,)]]]]]
    print sum(hits(1, lst, 1, 1, 1))
    
    15
    
    29.04.2011
  • +1 за самого крутого lambda обидчика здесь ;-). Это также отвечает на вопрос, как рекурсивно встроить генератор в себя :-). 29.04.2011

  • 6
    def nested_count(lst, x):
        return lst.count(x) + sum(
            nested_count(l,x) for l in lst if isinstance(l,list))
    

    Эта функция возвращает количество вхождений, плюс рекурсивный вложенный счетчик во всех содержащихся подсписках.

    >>> data = [[1,2,3],[1,1,[1,1]]]
    >>> print nested_count(data, 1)
    5
    
    29.04.2011

    7

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

    def flatten(listOrItem, result = None):
        if result is None: result = []      # Ensure initial result empty.
    
        if type(listOrItem) != type([]):    # Handle non-list by appending.
            result.append(listOrItem)
        else:
            for item in listOrItem:         # Recursively handle each item in a list.
                flatten(item, result)
        return result                       # Return flattened container.
    
    mylist = flatten([[1,2],[3,'a'],[5,[6,7,[8,9]]],[10,'a',[11,[12,13,14]]]])
    print(f'Flat list is {mylist}, count of "a" is {mylist.count("a")}')
    
    print(flatten(7))
    

    Если у вас есть сплющенный список, можно просто использовать в нем count. Результат этого кода:

    Flat list is [1, 2, 3, 'a', 5, 6, 7, 8, 9, 10, 'a', 11, 12, 13, 14], count of "a" is 2
    [7]
    

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


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

    def deepCount(listOrItem, searchFor):
        if type(listOrItem) != type([]): # Non-list, one only if equal.
            return 1 if listOrItem == searchFor else 0
    
        subCount = 0                     # List, recursively collect each count.
        for item in listOrItem:
            subCount += deepCount(item, searchFor)
        return subCount
    
    deepList = [[1,2],[3,'a'],[5,[6,7,[8,9]]],[10,'a',[11,[12,13,14]]]]
    print(f'Count of "a" is {deepCount(deepList, "a")}')
    print(f'Count of 13  is {deepCount(deepList, 13)}')
    print(f'Count of 99  is {deepCount(deepList, 99)}')
    

    Как и ожидалось, результат такой:

    Count of "a" is 2
    Count of 13  is 1
    Count of 99  is 0
    

    (a) Конечно, вплоть до ограничений, налагаемых самим Python, ограничения, которые вы можете увеличить, просто добавив это в начало вашего кода:

    import sys
    sys.setrecursionlimit(1001) # I believe default is 1000.
    

    Я упоминаю, что только в случае у вас есть несколько очень глубоко вложенных структур, но вам это действительно не нужно. Если вы так глубоко вложены, то, вероятно, делаете что-то не так :-)

    16.10.2020

    8
  • @RestRisiko: Где в вопросе говорится, что требуется произвольное вложение? Ваш собственный ответ на этот вопрос даже не касается этого, но вы будете голосовать против других? 29.04.2011
  • Почему люди голосуют против очень правильных ответов. Я поставил за это +1, и он мне нравится больше, чем мой ответ. Но мой ответ не был дерьмовым, и определенно не этот !!! 29.04.2011
  • @manojlds, @Thomas: Не беспокойтесь о троллях. Это совершенно правильный ответ с учетом требований OP. 29.04.2011
  • Это лучший ответ, который я когда-либо видел. Спасибо! 11.03.2020
  • Почему мы используем sum :( пожалуйста, объясните немного. 11.03.2021
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..