Список понимания кортежа достается мне генератором - зачем и как модифицировать? - PullRequest
0 голосов
/ 21 ноября 2018

Я выполняю упражнения этого сайта https://anandology.com/python-practice-book/working-with-data.html, когда я пытался воссоздать функцию zip с помощью понимания списка.Теперь я создал эту функцию.Но вместо того, чтобы получить список, я получаю генератор :-(

def zipp (liste1,liste2):
    length= len(liste1)
    zipped=[]
    [zipped.append(tuple(liste1[i], liste2[i]) for i in range(length))]
    return zipped

Я немного искал здесь и нашел это: Python: почему понимание списка приводит к генератору?

Соответственно, я уже использовал выражение "tuple", но без течения.

Я понятия не имею, почему я получаю генератор даже со вставленным tuple (). Поэтому мои вопросы:

  1. почему?
  2. Что мне нужно изменить или где я могу прочитать / услышать больше, чтобы самому "просветиться"?
  3. Как я могу использовать генератор, чтобы получить результат?(или где я могу прочитать об этом?)

Спасибо.

edit: я ожидаю получить список кортежей с элементами каждого списка в нем. Это то, что я долженget:

zipp ([1, 2, 3], ["a", "b", "c"]) -> [(1, "a"), (2, "b"), (3, "c")]

Ответы [ 2 ]

0 голосов
/ 21 ноября 2018

пытается ответить на ваши вопросы ...

1.- почему?

A: Как многие уже упоминали, вы возвращаете список zipped какгенераторы списков в пределах списка [zipped.append(tuple(liste1[i], liste2[i]) for i in range(length))], кстати, не очень хороший способ.вот почему вы получаете эти генераторы.

2.- Что мне нужно изменить или где я могу прочитать / услышать больше, чтобы самому "просветиться"?

A: Если вы все еще хотите сделать это, вам нужно только добавить два элемента, сдвинув скобки и удалив функцию кортежа, например так:

def zipp (liste1, liste2):
    length = len(liste1)
    zipped = []
    [zipped.append( (liste1[i], liste2[i]) ) for i in range(length) ]  # not the best way, but still works. This created list is never used.
    return zipped

, тогда можно вернуть список

zipp([1,2,3], ['a','b','c'])

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

min(len(liste1), len(liste2))

3.- Как я могу использовать генератор, чтобы получить результат?

A: Для того, чтобы он был генератором, вам нужно вывести нужное значение:

def zipp2 (liste1,liste2):
    i = 0
    minval = min(len(liste1), len(liste2))
    while i< minval:
        yield (liste1[i], liste2[i])
        i += 1

# call the function generator
gen = zipp2([1,2,3], ['a','b','c'])
print(gen)
for p in gen:
    print(p)

и получите результаты ...

<generator object zipp2 at 0x7fe46bef3db0>
(1, 'a')
(2, 'b')
(3, 'c')
0 голосов
/ 21 ноября 2018

вы помещаете генератор в ваш объект:

tuple(liste1[i], liste2[i]) for i in range(length)

tuple тоже не работает, просто удалите его ...)

(и не использовать понимания для побочных эффектов)

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

def zipp (liste1,liste2):
    return [(liste1[i], liste2[i]) for i in range(min(len(liste1),len(liste2)))]

версия классического цикла (без понимания)

def zipp (liste1,liste2):
   result = []
   for i in range(min(len(liste1),len(liste2))):
       result.append((liste1[i], liste2[i]))
   return result

конечно, это не что иное, как list(zip(liste1,liste2)) (принудительное выполнение итерации zip)

...