У меня есть два списка:
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'
Я не слишком хорошо знаком с генераторами, но мне кажется, что это наиболее полезно для запуска функций по частям за раз.
Сначала я использовал его, когда использовал генератор для chunk_l1 = list1_split(l1)
, сохраняя при этом l2
как обычный список, поэтому я создал два генератора, чтобы посмотреть, исправит ли это ситуацию, а затем, когда я запустил отладчик, чтобы посмотреть, что он делает, я заметил, как он интерпретировал списки генераторов, которые сбили меня с толку.
Для начала вы передаете None
в threading.Thread(target=query(chunk_l1, chunk_l2))
, так как query
всегда возвращает None
... но вам нужно предоставить минимальный воспроизводимый пример.
Хороший звонок, та же ошибка, я обновлю сообщение
Параметр target
должен быть функцией. Вы вызываете функцию query()
и передаете ее значение (словарь), а не саму функцию.
@SebastianGoslin хорошо, теперь вы передаете ему объект dict
, когда он ожидает вызываемый объект (например, функцию). Отсюда и ошибка TypeError: 'dict' object is not callable
.
На самом деле вы ничего не обрабатываете по частям. Функция query()
проходит через все куски и помещает все в query_return_dict
. В чем смысл дробления?
Начнем с того, что 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 ().
в какой строке вы получаете ошибку
TypeError: 'dict' object is not callable
?