Как получить длину всех токенов всего списка для данного входного файла в Python? - PullRequest
0 голосов
/ 29 октября 2018

Предположим, у меня есть список (L1), подобный этому:

 L1 = [['1', '0', '0', '0'], ['1', '0', '0', '0'], ['0', '0', '0', '1'], ['1', '0', '0', '0'], ['0', '0', '0', '1'], ['0', '0', '1', '0'], ['1', '0', '0', '0'], ['1', '0', '0', '0'], ['0', '0', '0', '1'], ['0', '0', '0', '1'], ['0', '0', '0', '1'], ['1', '0', '0', '0'], ['0', '0', '0', '1'], ['0', '0', '0', '1'], ['0', '0', '0', '1'], ['1', '0', '0', '0'], ['1', '0', '0', '0'],['0', '0', '0', '0']]

Если я использую len(L1), он возвращает 18, то есть общее количество списков для данного ввода.

Что если мне нужно вычислить общее количество токенов для списка ввода? Как этого добиться? Поскольку каждый список содержит 4 токенов, разделенных comma разделителем. Тогда для этого списка в общей сложности 72 токенов?

Существует ли способ достичь этого в Python 3? Любая помощь очень ценится!

Ответы [ 2 ]

0 голосов
/ 29 октября 2018

Попробуйте что-то вроде:

tokens = 0
for lst in L1:
      tokens += len(lst)

print tokens

Вы можете перебирать списки списков и суммировать все вхождения.

0 голосов
/ 29 октября 2018

Для вашего простого примера просто сложите длины вложенных списков:

sum(map(len, L1))

Это работает, потому что все, что у вас есть, это один уровень вложенности; внешний список содержит только вложенные списки, каждый из которых содержит только строки. sum() с map() - очень быстрый метод получения общей длины; все обрабатывается в C-коде, цикл оценки Python не должен проходить через цикл for.

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

len(L1) * 4

Это еще быстрее; итерации вообще не нужно было запрашивать для каждого вложенного списка объектов по их длине. Тем не менее, мы говорим о 0,76 против 0,07 микросекунд здесь, вряд ли проблема в любой программе Python. Подход с циклом for в виде , публикуемый Frame , занимает примерно вдвое больше времени, 1,33 микросекунды. Не совсем вечность.

Если ваши входные данные не являются регулярными (то есть смесь списков на разных уровнях вложенности), но в остальном состоят только из списков объектов, вам нужно будет выполнить итерацию и решить для каждого элемента, что делать. Вот основанная на стеке функция, которая будет считать все элементы, не относящиеся к списку, в такой структуре:

def total_length(irregular):
    total = 0
    stack = [irregular]
    while stack:
        ob = stack.pop()
        if not isinstance(ob, list):
            total += 1
        else:
            stack.extend(ob)
    return total

Вышеприведенное может быть расширено для охвата кортежей и т. Д. Путем добавления к тесту isinstance() по мере необходимости.

Демо-версия:

>>> L1 = [['1', '0', '0', '0'], ['1', '0', '0', '0'], ['0', '0', '0', '1'], ['1', '0', '0', '0'], ['0', '0', '0', '1'], ['0', '0', '1', '0'], ['1', '0', '0', '0'], ['1', '0', '0', '0'], ['0', '0', '0', '1'], ['0', '0', '0', '1'], ['0', '0', '0', '1'], ['1', '0', '0', '0'], ['0', '0', '0', '1'], ['0', '0', '0', '1'], ['0', '0', '0', '1'], ['1', '0', '0', '0'], ['1', '0', '0', '0'], ['0', '0', '0', '0']]
>>> sum(map(len, L1))
72
>>> irregular = ['foo', ['spam', 'ham'], ['bar', ['monty', 'python', ['eric', 'idle'], 'vikings'], 42]]
>>> total_length(irregular)
10
...