Запуск функции в обычном списке и списке генераторов

У меня есть два списка:

l1 = ['a','b','c','d','e','f','g','h', ...]

l2 = ['dict1','dict2','dict3','dict4','dict5','dict6','dict7','dict8', ...]

Мне нужно запустить функцию для фрагмента каждого списка по 50 элементов за раз, и она не может продолжаться до тех пор, пока функция не вернет результат первых 50 элементов в каждом списке.

Моя первая идея заключалась в использовании генератора:

def list1_split(l1):
    n = 50
    for i in range(0, len(l1), n):
        yield l1[i:i+n]

def list2_split(l2):
        n = 50
        for i in range(0, len(l2), n):
            yield l2[i:i+n]

chunk_l1 = list1_split(l1)
chunk_l2 = list1_split(l1)

Затем при использовании обоих списков я помещаю их в основную функцию:

def query(chunk_l1, chunk_l2):

    count = 0
    query_return_dict = {}

    for i, j in zip(chunk_l2, chunk_l1):
        count += 1
        query_return_dict[i] = j
        print('This is number ', count, '\n', j)

    return query_return_dict


def main():
    thread = threading.Thread(target=query(chunk_l1, chunk_l2))
    thread.start()

    print('Done!')

if __name__ == '__main__':
    main()

Моя первая ошибка, которую я получаю, не связана с генераторами (я думаю):

TypeError: 'dict' object is not callable

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

i: <class 'list'>: ['a','b','c','d','e',...]
j: <class 'list'>: ['dict1','dict2','dict3','dict4',...]

Вместо i: 'a', j: 'dict1', кроме того, я получаю сообщение об ошибке:

TypeError: unhashable type: 'list'

Я не слишком хорошо знаком с генераторами, но мне кажется, что это наиболее полезно для запуска функций по частям за раз.

в какой строке вы получаете ошибку TypeError: 'dict' object is not callable ?

Devesh Kumar Singh 12.06.2019 21:33

Сначала я использовал его, когда использовал генератор для chunk_l1 = list1_split(l1), сохраняя при этом l2 как обычный список, поэтому я создал два генератора, чтобы посмотреть, исправит ли это ситуацию, а затем, когда я запустил отладчик, чтобы посмотреть, что он делает, я заметил, как он интерпретировал списки генераторов, которые сбили меня с толку.

Sebastian Goslin 12.06.2019 21:35

Для начала вы передаете None в threading.Thread(target=query(chunk_l1, chunk_l2)), так как queryвсегда возвращает None... но вам нужно предоставить минимальный воспроизводимый пример.

juanpa.arrivillaga 12.06.2019 21:38

Хороший звонок, та же ошибка, я обновлю сообщение

Sebastian Goslin 12.06.2019 21:40
stackoverflow.com/questions/11792629/…
user2357112 supports Monica 12.06.2019 21:44

Параметр target должен быть функцией. Вы вызываете функцию query() и передаете ее значение (словарь), а не саму функцию.

Barmar 12.06.2019 21:45

@SebastianGoslin хорошо, теперь вы передаете ему объект dict, когда он ожидает вызываемый объект (например, функцию). Отсюда и ошибка TypeError: 'dict' object is not callable.

juanpa.arrivillaga 12.06.2019 21:48

На самом деле вы ничего не обрабатываете по частям. Функция query() проходит через все куски и помещает все в query_return_dict. В чем смысл дробления?

Barmar 12.06.2019 21:48
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
4
8
61
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Начнем с того, что i и j — это не строки, как вы могли подумать, а сами списки.

Когда вы делаете query_return_dict[i], вы получаете сообщение об ошибке TypeError: unhashable type: 'list', так как вы пытаетесь использовать список в качестве ключа словаря, но вы не можете этого сделать, поскольку списки изменяемы и, следовательно, не могут хешироваться, а ключи словаря всегда должны быть хешируемыми.

Чтобы извлечь строки из списка, вам нужен еще один цикл for, который перебирает i и j и создает ваш query_return_dict

def query(chunk_l1, chunk_l2):

    query_return_dict = {}

    #i and j are chunks
    for i, j in zip(chunk_l1, chunk_l2):
        #Zip chunks together to extract individual elements
        for key, value in zip(i, j):
            #Create your dictionary
            query_return_dict[key] = value

Кроме того, thread = threading.Thread(target=query(chunk_l1, chunk_l2)) - это не то, как вы передаете функцию в качестве цели в поток, вместо этого вы хотели бы сделать

thread = threading.Thread(target=query, args=(chunk_l1, chunk_l2))

Из документов: https://docs.python.org/3/library/threading.html#threading.Thread

target is the callable object to be invoked by the run() method. Defaults to None, meaning nothing is called.
args is the argument tuple for the target invocation. Defaults to ().

Другие вопросы по теме