Python, выкарыстоўваючы функцыю zip(): Атрыманне элементаў некалькіх спісаў адначасова

Бізнэс

Убудаваная функцыя zip() Python аб’ядноўвае элементы некалькіх ітэрацыйных аб’ектаў (спісы, картэжы і г.д.) і выкарыстоўваецца для атрымання элементаў некалькіх спісаў у цыкле for.

У гэтым раздзеле апісваецца наступнае выкарыстанне функцыі zip().

  • Атрымаць элементы некалькіх спісаў у цыкле for.
  • Праца з рознай колькасцю элементаў
    • zip():Функцыя будзе ігнараваць элементы, якіх занадта шмат.
    • itertools.zip_longest():Гэтая функцыя запоўніць адсутнічаюць элементы.
  • Атрымаць спіс картэжаў элементаў некалькіх ітэрабельных.

Атрымаць элементы некалькіх спісаў у цыкле for.

Калі вы хочаце адначасна здабываць і выкарыстоўваць элементы некалькіх ітэрацыйных аб’ектаў (спісаў, картэжаў і г.д.) у цыкле for, укажыце іх у якасці аргументаў для функцыі zip().

names = ['Alice', 'Bob', 'Charlie']
ages = [24, 50, 18]

for name, age in zip(names, ages):
    print(name, age)
# Alice 24
# Bob 50
# Charlie 18

Не толькі два, але і тры ці больш.

points = [100, 85, 90]

for name, age, point in zip(names, ages, points):
    print(name, age, point)
# Alice 24 100
# Bob 50 85
# Charlie 18 90

Праца з рознай колькасцю элементаў

Функцыя zip() ігнаруе вялікую колькасць элементаў.

У функцыі zip() калі колькасць элементаў у кожным спісе адрозніваецца, будзе вернутая колькасць элементаў да меншай (кароткі), а большая колькасць ігнаруецца.

names = ['Alice', 'Bob', 'Charlie', 'Dave']
ages = [24, 50, 18]

for name, age in zip(names, ages):
    print(name, age)
# Alice 24
# Bob 50
# Charlie 18

Функцыя itertools.zip_longest() запоўніць адсутныя элементы.

Выкарыстоўваючы zip_longest() у стандартнай бібліятэцы itertools модулі, можна запоўніць адсутныя элементы адвольнымі значэннямі, калі колькасць элементаў у кожным спісе розная.

Па змаўчанні ён запоўнены None.

from itertools import zip_longest

names = ['Alice', 'Bob', 'Charlie', 'Dave']
ages = [24, 50, 18]

for name, age in zip_longest(names, ages):
    print(name, age)
# Alice 24
# Bob 50
# Charlie 18
# Dave None

Калі зададзены аргумент fillvalue, ён будзе запоўнены гэтым значэннем.

for name, age in zip_longest(names, ages, fillvalue=20):
    print(name, age)
# Alice 24
# Bob 50
# Charlie 18
# Dave 20

Нават калі ёсць некалькі спісаў з адсутнымі элементамі, значэнне, якое трэба запоўніць, аднолькавае. Немагчыма паказаць розныя значэнні.

points = [100, 85]

for name, age, point in zip_longest(names, ages, points, fillvalue=20):
    print(name, age, point)
# Alice 24 100
# Bob 50 85
# Charlie 18 20
# Dave 20 20

Можна задаць іншае значэнне, выкарыстоўваючы zip_longest() у zip_longest(), але гэта непрактычна, таму што вам трэба загадзя ведаць, якія элементы спісу адсутнічаюць.

Калі вы хочаце запоўніць некалькі спісаў невядомай колькасцю элементаў, кожны з якіх мае рознае значэнне, можна разгледзець наступную працэдуру.

  1. Вызначце значэнні для запаўнення для ўсіх спісаў.
  2. Атрымаць максімальную колькасць элементаў
  3. Запоўніце ўсе спісы да максімальнай колькасці элементаў
  4. Выкарыстанне функцыі zip().
fill_name = 'XXX'
fill_age = 20
fill_point = 50

len_names = len(names)
len_ages = len(ages)
len_points = len(points)

max_len = max(len_names, len_ages, len_points)

names = names + [fill_name] * (max_len - len_names)
ages = ages + [fill_age] * (max_len - len_ages)
points = points + [fill_point] * (max_len - len_points)

print(names)
print(ages)
print(points)
# ['Alice', 'Bob', 'Charlie', 'Dave']
# [24, 50, 18, 20]
# [100, 85, 50, 50]

for name, age, point in zip(names, ages, points):
    print(name, age, point)
# Alice 24 100
# Bob 50 85
# Charlie 18 50
# Dave 20 50

У працэсе запаўнення да найбольшай колькасці элементаў робім наступнае.

  • Ініцыялізацыя спісу з адвольным значэннем і колькасцю элементаў
  • + аператар для аб’яднання спісаў разам

Калі мы ператворым гэта ў функцыю, гэта выглядае так. Зыходны спіс і значэнні, якія запаўняюць спіс, зададзены ў выглядзе ітэрацыйных (спіс або картэж) аргументаў адпаведна.

def my_zip_longest(iterables, fillvalues):
    max_len = max(len(i) for i in iterables)
    return zip(*[list(i) + [v] * (max_len - len(i)) for i, v in zip(iterables, fillvalues)])

for name, age, point in my_zip_longest((names, ages, points), ('XXX', 20, 50)):
    print(name, age, point)
# Alice 24 100
# Bob 50 85
# Charlie 18 50
# Dave 20 50

Ён выкарыстоўвае абазначэнне разумення спісу і пашырэнне спісу на *.

Атрымаць спіс картэжаў элементаў некалькіх ітэрабельных.

Функцыя zip() вяртае ітэратар (аб’ект zip), які ўяўляе сабой набор элементаў некалькіх ітэрацыйных аб’ектаў.
Ён таксама можа быць выкарыстаны па-за цыклам for, і мэта не абмяжоўваецца спісамі.

names = ['Alice', 'Bob', 'Charlie']
ages = (24, 50, 18)

z = zip(names, ages)
print(z)
print(type(z))
# <zip object at 0x10b57b888>
# <class 'zip'>

Калі вы хочаце атрымаць спіс элементаў некалькіх ітэрацыйных аб’ектаў у выглядзе картэжа, выкарыстоўвайце list(), каб скласці спіс.

l = list(zip(names, ages))
print(l)
print(type(l))
print(type(l[0]))
# [('Alice', 24), ('Bob', 50), ('Charlie', 18)]
# <class 'list'>
# <class 'tuple'>